@woosh/meep-engine 3.60.4 → 3.60.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/CHANGELOG.md +2602 -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.map +1 -1
  63. package/src/shade/renderer/Renderer.js +7 -5
  64. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  67. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  68. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  69. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  70. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  71. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  72. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
  74. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  75. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  77. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  78. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  80. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  81. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  82. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  83. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  85. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  86. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  87. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  88. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  98. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  99. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  100. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  101. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  102. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  104. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  105. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  106. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  107. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  108. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  109. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  110. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  111. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  112. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  113. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  114. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  115. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  116. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  117. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  118. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  119. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  120. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  121. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  122. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  123. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  124. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  126. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  127. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  128. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  129. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  130. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  131. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  132. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  133. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  134. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  135. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  136. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  137. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  138. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  139. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  140. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  141. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  142. package/src/shade/renderer/water/shader_water.js +22 -13
  143. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  144. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  145. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  146. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  147. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  148. package/editor/REWORK_PLAN_2026_08.md +0 -692
  149. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  150. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  151. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  152. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  153. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  154. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  155. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  156. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  157. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  158. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  159. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  160. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  161. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  162. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  163. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  164. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  165. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  166. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  167. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  168. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  169. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  170. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  171. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  172. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  173. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  174. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  175. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  176. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  177. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  178. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  179. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  180. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  181. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  182. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  183. package/src/REVIEW_2026_08_06/generation.md +0 -176
  184. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  185. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  186. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  187. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  188. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  189. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  190. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  191. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  192. package/src/REVIEW_2026_08_06/view.md +0 -667
  193. package/src/REVIEW_2026_08_06.md +0 -610
  194. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  195. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  196. package/src/core/bvh8/NOTES.md +0 -63
  197. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  198. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  199. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  200. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  201. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  202. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  203. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  204. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  205. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  206. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  207. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  208. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  209. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  210. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  211. package/src/engine/REVIEW_2026_07_03.md +0 -211
  212. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  213. package/src/engine/control/first-person/DESIGN.md +0 -658
  214. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  215. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  216. package/src/engine/control/first-person/TODO.md +0 -160
  217. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  218. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  219. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  220. package/src/engine/ecs/ik/PLAN.md +0 -179
  221. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  222. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  223. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  224. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  225. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  226. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  227. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  228. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  229. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  230. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  231. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  232. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  233. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  234. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  235. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  236. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  237. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  238. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  239. package/src/engine/physics/cloth/PLAN.md +0 -3056
  240. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  241. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  242. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  243. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  244. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  245. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  246. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  247. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  248. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  249. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  250. package/src/format/image/avif/DECISIONS.md +0 -545
  251. package/src/format/image/jpeg/NOTES.md +0 -3
  252. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  253. package/src/generation/COORDINATES.md +0 -54
  254. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  255. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  256. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  257. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  258. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  259. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  260. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  261. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  262. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  263. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  264. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  265. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  266. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  267. package/src/shade/RENDERER_CONTRACT.md +0 -697
  268. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  269. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  270. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  271. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  272. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  273. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  274. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  275. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  276. package/src/shade/renderer/NOTES.md +0 -78
  277. package/src/shade/renderer/PLAN.md +0 -8
  278. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  279. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  280. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  281. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  282. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  283. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  284. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  285. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  286. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  287. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  288. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  289. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  290. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  291. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  292. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  293. package/src/shade/renderer/camera/orbital/README.md +0 -81
  294. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  295. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  296. package/src/shade/renderer/camera/orbital/index.js +0 -9
  297. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  298. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  299. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  300. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  301. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  302. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  303. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  304. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  305. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  306. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  307. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  308. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  309. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  310. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  311. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  312. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  313. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  314. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  315. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  316. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  317. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  318. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  319. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  320. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  321. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  322. package/src/shade/renderer/hiz/NOTES.md +0 -3
  323. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  324. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  325. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  326. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  327. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  328. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  329. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  330. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  331. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  332. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  333. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  334. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  335. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  336. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  337. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  338. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  339. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  340. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  341. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  342. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  343. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  344. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  345. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  346. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  347. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  348. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  349. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  350. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  351. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  352. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  353. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  354. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  355. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  356. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  357. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  358. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  359. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  360. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  361. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  362. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  363. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  364. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  365. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  366. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  367. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  368. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  369. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  370. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  371. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  372. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  373. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  374. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  375. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  376. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  377. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  378. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  379. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,382 +0,0 @@
1
- # Collision handling — ground-up construction plan
2
-
3
- > **Status, because this reads as a plan and a reader has to know how much of it is real.**
4
- > Steps 1–4 of §4's sequence are **shipped** in `collision/KinematicMover.js`: recover (`_recover`,
5
- > `compute_penetration`), slide (`_slide`, `MAX_CLIP_PLANES` crease handling), stairs
6
- > (`_tryStepUp`), and ground categorise + stick + slope clip (`_categorizeGround`). The mover's own
7
- > docblock still says "Phase 1" in places; the phase numbering here is the order things were built
8
- > in, not what exists. **Not shipped:** a moving-platform step — nothing carries a character on a
9
- > lift, and `MoveResult` reports `groundBody`/`groundEntity` so a consumer can write the carry
10
- > themselves until there is one.
11
- >
12
- > **This solver is controller-agnostic and the path lies about that.** `KinematicMover` imports
13
- > `Vector3`, `Ray3`, `Transform`, `Collider`, `compute_penetration` and `PhysicsSurfacePoint` —
14
- > nothing from the controller — and it is the right thing to use even if you have decided
15
- > `FirstPersonPlayerController` is not for you. It lives here because this is where it was built,
16
- > and a consumer who ruled out the controller has been given a path saying these files are not for
17
- > them either. A port did exactly that and spent about six hours re-implementing the standoff
18
- > (`skin`) and the depenetration pass it already has (GAP-021).
19
-
20
- Companion to DESIGN.md (base controller) and TODO.md.
21
-
22
- **Premise.** The control layer is excellent and stays. The collision
23
- layer is being **replaced wholesale** — the current
24
- `_moveAndSlide` + `_integrateVerticalAndResolveGround` + scalar
25
- ground-resolver regime is not a foundation to build on; it's scaffolding
26
- to delete once the replacement reaches parity. We keep relying on
27
- `PhysicsSystem` for all the heavy lifting (`shapeCast`, `raycast`,
28
- `overlap`, `compute_penetration`) — this plan does *more* with it, not
29
- less.
30
-
31
- Every phase is **guard-test-first**, and ordered so the controller stays
32
- shippable and green after each one. The new mover is built alongside,
33
- proven against ported + new specs, switched over, and only then is the
34
- old code deleted.
35
-
36
- ---
37
-
38
- ## 1. The seam: control produces motion, collision resolves it
39
-
40
- The clean split that makes a ground-up rebuild safe — the control layer
41
- already does its half today:
42
-
43
- ```
44
- CONTROL (sacred, unchanged) COLLISION (rebuilt)
45
- ────────────────────────── ──────────────────
46
- intent → desired velocity move(pose, shape, velocity, dt)
47
- accel curves, jump FSM, ──v──▶ → resolved position
48
- gravity/impulse, abilities, → corrected velocity
49
- mastery, posture → ground state {grounded, normal}
50
- ▲ │
51
- └────────── grounded, groundNormal ◀─────────┘
52
- (read next tick by jump FSM,
53
- gravity gating, slope logic)
54
- ```
55
-
56
- The control layer's output each tick is a **desired velocity** (it
57
- already computes this — intent+accel horizontally, gravity+jump
58
- vertically). The collision layer's *only* job is: given that velocity,
59
- the capsule pose, and the world, produce the actual resulting position,
60
- the velocity corrected for what it hit, and the ground state. It never
61
- invents motion; it only constrains it.
62
-
63
- One cleanup this forces (Phase 4): **gravity + jump-impulse application
64
- move out of the deleted collision method into a small motor helper**
65
- the base loop and abilities call. The solver stays purely about
66
- collision.
67
-
68
- ---
69
-
70
- ## 2. What we keep / replace / delete
71
-
72
- **Keep (untouched):** the whole control stack — intent, mono-exp accel,
73
- jump FSM, posture→collider sizing, abilities (Slide/WallRun/Mantle/
74
- LedgeGrab), mastery, camera composition, sensors.
75
-
76
- **Replace:** the regime that *consumes* velocity —
77
- `_moveAndSlide` (horizontal-only swept slide), the direct vertical
78
- position add, and the downward-ray scalar-Y ground snap.
79
-
80
- **Delete (Phase 4, after parity):** `_moveAndSlide`,
81
- `_integrateVerticalAndResolveGround`'s collision body, the
82
- `CAST_STEP_HEIGHT` implicit-step hack, and the scalar `groundResolver`
83
- *as the grounding authority* (it survives only as a no-physics fallback
84
- inside the new ground probe).
85
-
86
- ---
87
-
88
- ## 3. Physics capabilities we build on
89
-
90
- The P1–P6 narrowphase/query work is the enabling foundation — the
91
- rebuild is only feasible because these are now narrowphase-exact.
92
-
93
- | Capability | Status | Source |
94
- |---|---|---|
95
- | `raycast` exact surface **normal** (sphere/box/capsule/mesh/heightmap) | ✅ | refine_ray_hit P1–P3 (`6f931b4`…`4c2292c`) |
96
- | `shapeCast` true contact **normal at TOI** (MPR, not broadphase −dir) | ✅ | `shape_cast.js` normal-recovery |
97
- | `shapeCast` **start-in-contact** → `t=0` + valid normal | ✅ | `shape_cast.js:195`, `:350` |
98
- | `shapeCast` analytic slab-narrowing (long-sweep accuracy) | ✅ | `shape_cast.js:203` |
99
- | `compute_penetration(out, A,pa,ra, B,pb,rb) → depth`, `out`=unit B→A | ✅ **public** | `compute_penetration.js:138` |
100
- | `overlap(shape,pos,rot,out,off,filter)` → body-id list | ✅ | `overlap_shape.js` |
101
- | EPA adaptive tol / MPR fallback / box-box edge / capsule-tri manifold / GJK cache | ✅ | P2.2, P3.1, P3.2, P1.1c, P2.1 |
102
-
103
- Contracts the plan honours:
104
- - `shapeCast` `result.t` is a **world distance** when direction is
105
- unit-length and `tMax = sweepLength`. New casts keep that.
106
- - `compute_penetration` accepts the convex player capsule vs any
107
- shape (only concave-vs-concave throws); `out_direction` is the unit
108
- **B→A** separation, depth is the scalar return. Push the capsule (A)
109
- out along `+out_direction · depth`.
110
- - `shapeCast` `result.position` is the swept **centre**, not the
111
- contact point — we derive ground-surface Y from the cast `t` + the
112
- capsule's bottom offset, so we never need a contact point.
113
-
114
- ---
115
-
116
- ## 4. Target architecture — a dedicated `KinematicMover`
117
-
118
- Extract the collision solver into its own module (name placeholder —
119
- `KinematicMover` / `CharacterMover`), testable in isolation against a
120
- real `PhysicsSystem`, not buried in the 1500-line system file. Matches
121
- the repo's extraction taste (Spring, EyeOffsetStack, FirstPersonSensors).
122
-
123
- It knows nothing about the controller — just a capsule, a velocity, the
124
- world, and an `up` axis. Single entry point:
125
-
126
- ```
127
- move(transform, shape, velocity, dt, filter) → MoveResult
128
- // mutates transform.position; returns:
129
- // { velocityX/Y/Z (corrected), grounded, groundNormal, hit }
130
- ```
131
-
132
- Modelled on modern kinematic character controllers (Jolt
133
- `CharacterVirtual`, Source `TryPlayerMove`+`CategorizePosition`), the
134
- move is an explicit sequence — **recover → slide → (stairs) → ground →
135
- settle**:
136
-
137
- 1. **Recover (depenetration).** Before moving, get clear. `overlap()`
138
- the capsule; for each body, `compute_penetration` → push the capsule
139
- out by `depth · dir`; iterate a few times (deepest-first) to
140
- convergence. Handles spawned-in-geometry, world-crushed-into-us, and
141
- the start-solid case a pure sweep *cannot*. This is now a **core
142
- step**, available from Phase 1 — not a bolt-on — because
143
- `compute_penetration` is public.
144
-
145
- 2. **Sweep-and-slide (unified 3D).** Sweep the *full* velocity·dt
146
- (gravity folded in — no H/V split) via `shapeCast`; stop at TOI,
147
- clip velocity onto the contact tangent, project the residual, repeat
148
- up to N iterations. **Crease-aware**: a second plane re-violating the
149
- first → project onto the seam `normalize(n₁×n₂)`; a third plane in
150
- one move → dead-stop. Walls, floors, ceilings are all just contact
151
- planes, so anti-tunnelling (H and V) falls out of one loop.
152
-
153
- 3. **Stairs (explicit, optional per move).** When grounded and blocked
154
- by a low step: sweep up by `stepHeight`, sweep the residual forward,
155
- sweep back down — the Jolt/Source step pattern. Replaces the 5 cm
156
- implicit-cast hack with real stair climbing, gated so walls taller
157
- than `stepHeight` still block.
158
-
159
- 4. **Ground categorize + stick.** Short downward `shapeCast` (capsule
160
- swept down a `SKIN + band`); if it hits within the band with
161
- `normal.y ≥ MIN_WALK_NORMAL` (~0.7), set `grounded`, capture the
162
- normal, snap to the surface, and kill the into-ground velocity
163
- component. Band-test + active snap (not a strict `y ≤ testY`) is what
164
- structurally kills the landing **bounce**. Too-steep normal →
165
- not grounded → the slope was already a slide plane in step 2, so the
166
- player slides down it.
167
-
168
- 5. **Settle.** One final `compute_penetration` recover pass guarantees
169
- the tick ends penetration-free (resting-contact float drift
170
- insurance; usually a no-op).
171
-
172
- **No-slip ⇔ walkable (one gate, not two).** Between recover and slide,
173
- when the feet rest on walkable ground (`_groundedAt` — a walkable normal
174
- within the stick band, the *same* `MIN_WALK_NORMAL` as step 4), the
175
- downward **gravity** velocity is dropped before the slide. Otherwise
176
- gravity projects onto a ramp's tangent as a downhill **drift** and a
177
- standing player creeps down every slope it can walk. A biped grips any
178
- slope it could walk up; the instant its feet slip it could not have
179
- climbed either — so *"doesn't slide down"* and *"can be walked up"* are
180
- the same threshold, not two independent tunables. A too-steep face fails
181
- the gate, keeps its gravity, and slides (step 4) — purchase and no-slip
182
- appear and vanish together as the one knob moves. A jump (`v.y > 0`) is
183
- exempt so the launch is never cancelled.
184
-
185
- Slope handling, multi-body resting contact, and unstick all fall out of
186
- steps 1/2/4 — no special cases. Abilities get correct collision for free
187
- by routing their motion through the same `move()`.
188
-
189
- ---
190
-
191
- ## 5. Phased plan (rebuild, not patch)
192
-
193
- ### Phase 1 — `KinematicMover`: recover + unified sweep-and-slide ✅ **landed**
194
- Stand up the module. Implement **recover** (overlap +
195
- compute_penetration) and **unified 3D sweep-and-slide** (crease-aware).
196
- The system calls `move()` for the combined velocity·dt, replacing both
197
- `_moveAndSlide` and the direct vertical add. Grounding stays on the old
198
- resolver as a short-lived interim shim (removed in Phase 2) so this
199
- phase isolates "does the new mover move correctly."
200
-
201
- **Guard tests** (`KinematicMover.spec.js`, against a real PhysicsSystem):
202
- spawn straddling a box → recovered outside within a tick; wall stop;
203
- slide-along axis-aligned + oblique wall; **vertical** anti-tunnel (drop
204
- through a thin slab → lands on top); jump into ceiling → stops; corner
205
- crease → clean stop, no leak/chatter. Port the existing
206
- `MoveAndSlide.spec.js` scenarios through the new path.
207
-
208
- **Risk:** medium. New module, but isolated; old grounding still in place.
209
-
210
- ### Phase 2 — Ground categorize + slope + stick (inside the mover) ✅ **landed**
211
- Add steps 4 (categorize/stick) to the mover. Down-`shapeCast` →
212
- `{grounded, normal}`; `MIN_WALK_NORMAL` gate; snap + kill into-ground
213
- velocity; reproject grounded velocity onto the slope. **Remove the
214
- interim grounding shim and the scalar resolver authority** (resolver
215
- demoted to no-physics fallback *inside* the probe, behind one function —
216
- uniform flow). Feed `grounded`/`groundNormal` back to control.
217
-
218
- **Guard tests** (`GroundSlope.spec.js`): walk up a 30° ramp keeps speed,
219
- stays grounded, correct normal; stationary-on-floor stays at y≈0 across
220
- 120 ticks (the no-bounce repro, now with nothing masking it); 60° face →
221
- not grounded, slides down, not glued.
222
-
223
- **Risk:** medium. Changes grounding semantics; the bounce reconciliation
224
- lives here.
225
-
226
- ### Phase 3 — Stairs ✅ **landed**
227
- Real stair climbing, gated by `stepHeight` (default 0.3 m, just under
228
- the capsule radius). Three cooperating pieces — it took iterating to
229
- find that all three are needed:
230
-
231
- 1. **Explicit step-up** (`_tryStepUp`, Source/Jolt up-forward-down).
232
- When a grounded move is blocked, decide step-vs-wall with a **thin
233
- horizontal ray at the step-height plane** (`sy + stepHeight + skin`),
234
- then — only if clear — lift by stepHeight, advance the residual
235
- forward, drop onto the step, commit when it gained ground within
236
- stepHeight, and **restore the horizontal velocity**. The velocity
237
- restore is the crux for REALISTIC stairs: the capsule's round bottom
238
- also rolls up low risers, but only with sustained forward momentum,
239
- and a controller that reads back the slide-clipped velocity loses
240
- that momentum at the riser and stalls. The step-up climbs without
241
- depending on momentum and hands the velocity back so the player keeps
242
- moving up the flight.
243
-
244
- The step-vs-wall ray is what stops the round bottom climbing a
245
- too-tall wall — and the reason it's a THIN ray, not the obvious
246
- "lift the capsule and sweep it forward" clearance cast: lifted so its
247
- tip sits at stepHeight, the capsule's rounded bottom narrows through
248
- the band `(stepHeight, stepHeight+radius)`, so a wall whose top lands
249
- in that band is never reached by the swept shape — it reads "clear"
250
- and the player climbs it, *faster speed reaching further into the
251
- round-off* (the gray-box bug: jitter at a walk, clean climb at a
252
- sprint). A thin ray has no round-off: it reads the obstacle's true
253
- height, so a step (top below the plane) is passed over and a wall
254
- (top above) is struck on its front face, at any approach speed.
255
-
256
- The ray is cast along the **blocked direction** (the horizontal
257
- velocity the slide removed = the obstacle's inward normal), from the
258
- **pre-slide** centre, reaching the swept distance plus a forward
259
- extent. Both matter for OBLIQUE approaches: at 45° the capsule meets a
260
- wall with its normal-direction extent, so a ray along *travel* stops
261
- short of the face and reads a wall as clear (climbing it); and
262
- rounding a convex corner the slide carries the *post*-slide centre
263
- just past the corner, so a ray from there shoots past the obstacle —
264
- the pre-slide centre was still in front of what blocked it. The reach
265
- tracking the sweep isn't the banned speed coupling: the climb-or-block
266
- decision is the step-height plane alone; the reach only governs how
267
- far ahead to look for what the slide already hit.
268
-
269
- A single ray still can't catch a convex *point*: grazing a corner a
270
- few degrees off its bisector, the blocked normal runs nearly parallel
271
- to a face, so the ray slips past the corner just outside the footprint
272
- and reads clear. The backstop is a post-hoc OVERLAP query — after
273
- up-forward-down, if the destination overlaps geometry the climb landed
274
- the round body ON a wall corner, not on a step (a real step top is
275
- rested on `skin` above, never overlapping), so it's rejected. Probe for
276
- the common case, overlap-test to catch what a ray threads past.
277
-
278
- The same round-bottom perch is why the slide keeps every contact's true
279
- normal (no "flatten steep contacts to vertical" — that would also rob
280
- a too-steep *slope* of its downhill slide) and why the footprint
281
- mount in (2) is gated on height above the **centre surface**, not the
282
- feet (gating on the feet lets a capsule that rode up a hair mount the
283
- next sliver and ratchet up a wall).
284
- 2. **Two-probe ground categorize** for honest grounded-ness on a step
285
- edge — *walkability* from a centre raycast (ignores a step's convex
286
- top edge and a wall's side face, so a steep *slope* is correctly
287
- not-grounded) and *rest height* from a footprint shapecast (mounts
288
- a step the leading edge overhangs). A single probe can't tell a
289
- climbable step edge from a steep slope; the split can.
290
- 3. **Step-DOWN** = the ground-stick reach is `stepHeight`: walking off
291
- a drop ≤ stepHeight snaps onto the lower surface (stays grounded);
292
- a larger drop goes airborne.
293
-
294
- Footgun caught in the prototype: my first stair test used *deep
295
- overlapping* steps, where the round-bottom roll alone climbs and the
296
- explicit step-up looked unnecessary. Realistic *thin* treads (shallower
297
- than the capsule footprint) need the step-up — see the thin-tread tests.
298
-
299
- **Guard tests** (`collision/Stairs.spec.js` + `KinematicMoverIntegration.spec.js`,
300
- all green): climb a 5-step staircase; climb a thin-tread staircase
301
- (treads < footprint) both at the mover level and through the full
302
- controller; clear a single curb; a 0.5 m riser (> stepHeight) blocks;
303
- a 0.5 m riser is a **clean wall — no edge ride-up, and clearing is
304
- speed-independent** (walk and sprint both stop dead, the gray-box guard);
305
- descend a staircase grounded the whole way.
306
-
307
- ### Phase 4 — Motor seam + delete old code ✅ **landed**
308
- The mover is now the **only** collision path when a `PhysicsSystem` is
309
- present — the opt-in flag is gone; dispatch is on physics presence, not
310
- a flag.
311
-
312
- What shipped:
313
- - `_integrateVerticalAndResolveGround` is now a thin dispatcher:
314
- `_applyGravity` (the motor) → `_moveViaMover` (physics) **or**
315
- `_moveFlatGround` (no physics) → `_detectJumpApex`.
316
- - **Gravity** extracted to `_applyGravity`; **land / leave-ground**
317
- extracted to `_onLand` / `_onLeaveGround`, shared by both move paths
318
- (the duplicated scaffolding from Phase 1's wiring is gone).
319
- - **Deleted** `_moveAndSlide` (+ its `CAST_STEP_HEIGHT` / `SKIN`
320
- constants and the `slideRay` / `slideHit` scratch), the legacy ground-
321
- resolution body, and the `useKinematicMover` flag.
322
- - `MoveAndSlide.spec.js` deleted — it tested `_moveAndSlide`; its
323
- scenarios (wall-stop, axis + oblique slide, anti-tunnel) are covered
324
- by `collision/KinematicMover.spec.js`.
325
-
326
- What stayed (deliberately):
327
- - `useBuiltInFlatGround` / `groundY` / `groundResolver` remain — they're
328
- the **no-physics** fallback (`_moveFlatGround`) for headless and
329
- control-layer unit tests, and the resolver is still spec-covered. With
330
- physics present they're unused (the mover probes the world).
331
- - **WallRun still self-integrates** its reduced-gravity model rather than
332
- routing through `move()`. Slide already routes through the mover (it
333
- calls `_integrateVerticalAndResolveGround`); WallRun's custom model is
334
- left as a future enhancement, not required for the legacy deletion.
335
-
336
- **Result:** 29 suites / 236 tests green; the entire ability + jump +
337
- momentum + posture suite passes through the consolidated path.
338
-
339
- ---
340
-
341
- ## 6. Physics requirements — status
342
-
343
- **Resolved.** My one HIGH ask from the review — a public penetration
344
- query — is **satisfied**: `compute_penetration` is public and is exactly
345
- the right shape (unit B→A direction + scalar depth, capsule-vs-anything).
346
- It graduates from "deferred safety net" to the **core recover/settle
347
- primitive** the whole mover leans on (steps 1 & 5). Confirmed it works:
348
- yes, this is precisely what's needed — thank you for keeping it decoupled
349
- and public.
350
-
351
- **No remaining blocking requirements.** Phases 1–4 need nothing further
352
- from the physics engine. The two low-priority niceties from the review
353
- turned out not to bite:
354
- - *Contact point from `shapeCast`* — not needed; ground-surface Y is
355
- derivable from the cast `t` + the capsule bottom offset.
356
- - *Multi-contact manifold from one query* — covered for resting contact
357
- by iterating `compute_penetration` over **every** `overlap()` body in
358
- the recover pass; the single-sweep corner case is handled by the slide
359
- iteration instead. So no native multi-contact query is required.
360
-
361
- If anything *would* be a future nicety (not needed now): a swept query
362
- returning the *set* of TOI-simultaneous contacts (for one-pass corner
363
- creases instead of iterating). Strictly an optimisation; the iterative
364
- slide is correct without it.
365
-
366
- ---
367
-
368
- ## 7. Constants (ours ← reference lineage)
369
-
370
- | Constant | Plan value | Reference | Phase |
371
- |---|---|---|---|
372
- | slide iterations | 4 | Quake `numbumps` 4 | 1 |
373
- | `SKIN` | 0.005 m | Fauerby `veryCloseDistance` ~0.005 | 1 |
374
- | recover max iters | ~4 | — (convergence cap) | 1 |
375
- | `MIN_WALK_NORMAL` | ~0.7 (≈45°) | Quake3 0.7 / Source `normal.z ≥ 0.7` | 2 |
376
- | ground-probe band | ~0.06 m | Source `StayOnGround` ~2 u | 2 |
377
- | crease dead-stop | zero on 3rd plane | Quake `SV_FlyMove` | 1 |
378
- | `stepHeight` | ~0.3 m (tunable) | Source `sv_stepsize` 18 u (~0.34 m) | 3 |
379
-
380
- Clip stays at effective overbounce `1.0` gated on into-wall (`v·n < 0`),
381
- relying on `SKIN` for clearance — equivalent in practice to Quake3's
382
- `OVERCLIP 1.001` nudge; no change planned.