@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
@@ -0,0 +1,70 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import { BufferResourceDescriptor } from "../../../shade/device/graph/BufferResourceDescriptor.js";
3
+ import { STRUCT_UNINDEXED_DRAW_COMMAND } from "../../../shade/renderer/gpu_primitive/indirect/STRUCT_UNINDEXED_DRAW_COMMAND.js";
4
+ import { build_indirect_draw_command } from "../../../shade/renderer/gpu_primitive/indirect/build_indirect_draw_command.js";
5
+ import { u32 } from "../../../shade/renderer/shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
6
+ import { DECAL_CLUSTER_TILE_RESOLUTION } from "./DECAL_CLUSTER.js";
7
+ import { shader_gather_decal_tiles } from "./shader_gather_decal_tiles.js";
8
+
9
+ /**
10
+ * Two triangles per tile, one instance per tile, the instance count read off the tile list's head.
11
+ *
12
+ * @type {string}
13
+ */
14
+ const DRAW_COMMAND_PATTERN = "6u, input, 0u, 0u";
15
+
16
+ /**
17
+ * List the screen tiles that hold a decal, and the draw command a `DecalTileShader` draws them with.
18
+ *
19
+ * The list holds every tile of the screen at worst, so it never drops one; what it costs to draw
20
+ * follows the count the gather wrote, through the command. The command has a buffer of its own, as
21
+ * an indirect argument may not be bound writable in the scope it is used in.
22
+ *
23
+ * @param {object} args
24
+ * @param {FrameGraph} args.graph
25
+ * @param {number} args.cluster_lookup handle of the decal froxels' lookup
26
+ * @param {number[]} args.resolution
27
+ * @returns {{tiles: number, command: number}}
28
+ */
29
+ export function graph_gather_decal_tiles({ graph, cluster_lookup, resolution }) {
30
+ assert.isNonNegativeInteger(cluster_lookup, 'cluster_lookup');
31
+ assert.isArrayLike(resolution, 'resolution');
32
+
33
+ const tile_count_x = Math.ceil(resolution[0] / DECAL_CLUSTER_TILE_RESOLUTION);
34
+ const tile_count_y = Math.ceil(resolution[1] / DECAL_CLUSTER_TILE_RESOLUTION);
35
+
36
+ const data = {};
37
+
38
+ const pass = graph.add("decal tiles / gather", data, (data, resources, context) => {
39
+ const encoder = context.encoder;
40
+ const tiles = resources.get(data.tiles);
41
+
42
+ shader_gather_decal_tiles.dispatchThreads({
43
+ encoder,
44
+ bindings: {
45
+ settings: { screen_resolution: resolution },
46
+ cluster_lookup: resources.get(data.cluster_lookup),
47
+ decal_tiles: tiles,
48
+ },
49
+ thread_count_x: tile_count_x,
50
+ thread_count_y: tile_count_y,
51
+ });
52
+
53
+ build_indirect_draw_command(encoder.device, DRAW_COMMAND_PATTERN, encoder, tiles, resources.get(data.command));
54
+ });
55
+
56
+ data.cluster_lookup = pass.read(cluster_lookup);
57
+
58
+ data.tiles = pass.create("decal tiles", BufferResourceDescriptor.from(
59
+ u32.size * (1 + tile_count_x * tile_count_y),
60
+ GPUBufferUsage.STORAGE,
61
+ 0, u32.size, // clear the count
62
+ ));
63
+
64
+ data.command = pass.create("decal tiles / draw command", BufferResourceDescriptor.from(
65
+ STRUCT_UNINDEXED_DRAW_COMMAND.aligned_size,
66
+ GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT,
67
+ ));
68
+
69
+ return { tiles: data.tiles, command: data.command };
70
+ }
@@ -1,18 +1,20 @@
1
1
  export const DECAL_COMPOSITE_SETTINGS: WebGPUStruct;
2
2
  /**
3
- * Reads the G-buffer, paints this frame's decals into it, and writes a new one.
3
+ * Paints this frame's decals into the G-buffer, in place, over the screen tiles that hold one.
4
4
  *
5
5
  * **Every channel is composited exactly, in registers.** Nothing is blended by hardware and nothing
6
6
  * is approximated: two of the four targets are integer formats that cannot blend at all, and the
7
7
  * previous shading normal and the ambient in the albedo's alpha both have to survive — which they
8
- * only can if the pass reads one texture and writes another (D23).
8
+ * only can if the pass reads one texture and writes another (D23). The one it reads is
9
+ * `shader_decal_tile_copy`'s copy of the same tiles, so only the covered part of the screen
10
+ * is read and written twice, rather than all of it once.
9
11
  *
10
12
  * The face normal is carried through untouched. A decal changes what a surface looks like, not which
11
13
  * way it is turned, and the face normal is what the fade and everything downstream reason about.
12
14
  *
13
- * @type {ImageShader}
15
+ * @type {DecalTileShader}
14
16
  */
15
- export const shader_decal_composite: ImageShader;
17
+ export const shader_decal_composite: DecalTileShader;
16
18
  import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
17
- import { ImageShader } from "../../../shade/renderer/shader/ImageShader.js";
19
+ import { DecalTileShader } from "./DecalTileShader.js";
18
20
  //# sourceMappingURL=shader_decal_composite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shader_decal_composite.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_decal_composite.js"],"names":[],"mappings":"AAgEA,oDAKG;AAySH;;;;;;;;;;;;GAYG;AACH,qCAFU,WAAW,CAclB;6BA1V0B,qDAAqD;4BAPtD,+CAA+C"}
1
+ {"version":3,"file":"shader_decal_composite.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_decal_composite.js"],"names":[],"mappings":"AAgEA,oDAKG;AA2SH;;;;;;;;;;;;;;GAcG;AACH,qCAFU,eAAe,CActB;6BA9V0B,qDAAqD;gCARlD,sBAAsB"}
@@ -1,5 +1,5 @@
1
- import { CAMERA_UNIFORM_STRUCT } from "../../../shade/renderer/camera/CAMERA_UNIFORM_STRUCT.js";
2
- import { VIEW_UNIFORM_STRUCT } from "../../../shade/renderer/view/VIEW_UNIFORM_STRUCT.js";
1
+ import { CAMERA_UNIFORM_STRUCT } from "../../../shade/renderer/camera/CAMERA_UNIFORM_STRUCT.js";
2
+ import { VIEW_UNIFORM_STRUCT } from "../../../shade/renderer/view/VIEW_UNIFORM_STRUCT.js";
3
3
  import { chunk_view_mip_bias } from "../../../shade/renderer/view/chunk_view_mip_bias.js";
4
4
  import { G_BUFFER_ALBEDO_FORMAT } from "../../../shade/renderer/gbuffer/G_BUFFER_ALBEDO_FORMAT.js";
5
5
  import {
@@ -35,8 +35,8 @@ import {
35
35
  } from "../../../shade/renderer/shader/chunk/texture/GRADIENT_SAMPLING_INFO_STRUCT.js";
36
36
  import { chunk_decal_sampling_info } from "./chunk_decal_sampling_info.js";
37
37
  import { chunk_decal_surface_frame } from "./chunk_decal_surface_frame.js";
38
+ import { DecalTileShader } from "./DecalTileShader.js";
38
39
  import { CodeChunk } from "../../../shade/renderer/shader/compiler/CodeChunk.js";
39
- import { ImageShader } from "../../../shade/renderer/shader/ImageShader.js";
40
40
  import {
41
41
  ShaderResourceSetDescriptor
42
42
  } from "../../../shade/renderer/shader/resource/ShaderResourceSetDescriptor.js";
@@ -75,7 +75,7 @@ const resources = new ShaderResourceSetDescriptor();
75
75
  resources.setImmediate("settings", DECAL_COMPOSITE_SETTINGS);
76
76
 
77
77
  resources.createGroup()
78
- .addUniform("camera", CAMERA_UNIFORM_STRUCT)
78
+ .addUniform("camera", CAMERA_UNIFORM_STRUCT)
79
79
  .addUniform("view", VIEW_UNIFORM_STRUCT);
80
80
 
81
81
  /*
@@ -93,7 +93,8 @@ resources.createGroup()
93
93
  resources.createGroup()
94
94
  .addStorageBuffer("decal_data", WebGPUArray.f32)
95
95
  .addStorageBuffer("cluster_lookup", WebGPUArray.from(DECAL_CLUSTER_METADATA))
96
- .addStorageBuffer("cluster_data", WebGPUArray.u32);
96
+ .addStorageBuffer("cluster_data", WebGPUArray.u32)
97
+ .addStorageBuffer("decal_tiles", WebGPUArray.u32);
97
98
 
98
99
  /*
99
100
  The three atlases are **filterable**, which is not the default a texture binding gets. Every one of
@@ -153,10 +154,11 @@ fn main(
153
154
  let old_emissive = textureLoad(gBufferEmissive, i_coord, 0).r;
154
155
 
155
156
  /*
156
- Every pixel is written, covered or not. The targets are fresh textures this pass hands
157
- downstream in place of the ones it read, so a pixel left alone here is not "unchanged" — it is
158
- undefined. Reading and writing the whole frame is the price of being able to composite exactly
159
- rather than through a blend the integer targets cannot do.
157
+ Every pixel this pass is drawn over is written, covered or not: the draw replaces what the
158
+ target held, and what it held is exactly what was read, so a pixel no decal touches is written
159
+ back unchanged. The inputs are a copy of the same texels taken by the pass before — one texture
160
+ cannot be attached and sampled at once — which is what lets the composite be exact rather than
161
+ a blend the integer targets cannot do.
160
162
  */
161
163
  var out : DecalCompositeOut;
162
164
 
@@ -179,34 +181,6 @@ fn main(
179
181
 
180
182
  let position = project_position_from_depth(uv, depth, camera.view_projection_matrix_inverse);
181
183
 
182
- let shading_normal = decode_g_buffer_normal(old_normal.xy);
183
- let face_normal = decode_g_buffer_normal(old_normal.zw);
184
-
185
- /*
186
- Screen-space world gradients, taken analytically off the surface rather than from 'dpdx'.
187
-
188
- Two reasons, and the first is that there is no choice: sampling inside a loop over a per-pixel
189
- decal list is non-uniform control flow, where WGSL forbids implicit derivatives — the same
190
- constraint that made the material pass interpolate its own from barycentrics. The second is
191
- that it is better anyway. A hardware derivative reads whatever the neighbouring pixel hit, so
192
- it lies across every silhouette; intersecting the neighbouring pixel's ray with *this* surface's
193
- plane answers the question actually being asked, which is how fast the decal's texture moves
194
- across the surface it is painted on.
195
- */
196
- let ray_here = normalize(project_position_from_depth(uv, 0.5, camera.view_projection_matrix_inverse) - camera_position);
197
- let ray_x = normalize(project_position_from_depth(uv + vec2<f32>(1.0 / resolution.x, 0.0), 0.5, camera.view_projection_matrix_inverse) - camera_position);
198
- let ray_y = normalize(project_position_from_depth(uv + vec2<f32>(0.0, 1.0 / resolution.y), 0.5, camera.view_projection_matrix_inverse) - camera_position);
199
-
200
- let plane_distance = dot(position - camera_position, face_normal);
201
-
202
- let denominator_x = dot(ray_x, face_normal);
203
- let denominator_y = dot(ray_y, face_normal);
204
-
205
- // grazing angles send these toward zero and the gradient toward infinity; the per-decal LOD
206
- // clamp is what keeps that finite, so nothing here needs to guard it
207
- let position_x = camera_position + ray_x * (plane_distance / denominator_x);
208
- let position_y = camera_position + ray_y * (plane_distance / denominator_y);
209
-
210
184
  let view_forward = -normalize(camera.view_matrix_inverse[2].xyz);
211
185
  let view_depth = dot(position - camera_position, view_forward);
212
186
 
@@ -232,10 +206,38 @@ fn main(
232
206
 
233
207
  let metadata = cluster_lookup[cluster_index];
234
208
 
209
+ // most pixels of a tile sit in a slice with no decal; they leave before any of the work below
235
210
  if (metadata.count == 0u) {
236
211
  return out;
237
212
  }
238
213
 
214
+ let shading_normal = decode_g_buffer_normal(old_normal.xy);
215
+ let face_normal = decode_g_buffer_normal(old_normal.zw);
216
+
217
+ /*
218
+ Screen-space world gradients, taken analytically off the surface rather than from 'dpdx'.
219
+
220
+ Two reasons, and the first is that there is no choice: sampling inside a loop over a per-pixel
221
+ decal list is non-uniform control flow, where WGSL forbids implicit derivatives — the same
222
+ constraint that made the material pass interpolate its own from barycentrics. The second is
223
+ that it is better anyway. A hardware derivative reads whatever the neighbouring pixel hit, so
224
+ it lies across every silhouette; intersecting the neighbouring pixel's ray with *this* surface's
225
+ plane answers the question actually being asked, which is how fast the decal's texture moves
226
+ across the surface it is painted on.
227
+ */
228
+ let ray_x = normalize(project_position_from_depth(uv + vec2<f32>(1.0 / resolution.x, 0.0), 0.5, camera.view_projection_matrix_inverse) - camera_position);
229
+ let ray_y = normalize(project_position_from_depth(uv + vec2<f32>(0.0, 1.0 / resolution.y), 0.5, camera.view_projection_matrix_inverse) - camera_position);
230
+
231
+ let plane_distance = dot(position - camera_position, face_normal);
232
+
233
+ let denominator_x = dot(ray_x, face_normal);
234
+ let denominator_y = dot(ray_y, face_normal);
235
+
236
+ // grazing angles send these toward zero and the gradient toward infinity; the per-decal LOD
237
+ // clamp is what keeps that finite, so nothing here needs to guard it
238
+ let position_x = camera_position + ray_x * (plane_distance / denominator_x);
239
+ let position_y = camera_position + ray_y * (plane_distance / denominator_y);
240
+
239
241
  let atlas_albedo_size = vec2<f32>(textureDimensions(atlas_albedo, 0));
240
242
  let atlas_normal_size = vec2<f32>(textureDimensions(atlas_normal, 0));
241
243
  let atlas_orm_size = vec2<f32>(textureDimensions(atlas_orm, 0));
@@ -246,8 +248,8 @@ fn main(
246
248
  var normal = shading_normal;
247
249
  var emissive = rgbe9995_decode(old_emissive);
248
250
 
249
- let uv_bias = view_uv_derivative_bias(view.upscale_ratio);
250
-
251
+ let uv_bias = view_uv_derivative_bias(view.upscale_ratio);
252
+
251
253
  for (var i = 0u; i < metadata.count; i++) {
252
254
  let decal_index = cluster_data[metadata.offset + i];
253
255
 
@@ -359,25 +361,27 @@ fn main(
359
361
  chunk_rgbe9995_encode,
360
362
  chunk_light_cluster_resolution_xy_from_screen,
361
363
  chunk_cluster_depth_to_z_slice,
362
- chunk_grid3d_to_index,
364
+ chunk_grid3d_to_index,
363
365
  chunk_view_mip_bias
364
366
  ]
365
367
  );
366
368
 
367
369
  /**
368
- * Reads the G-buffer, paints this frame's decals into it, and writes a new one.
370
+ * Paints this frame's decals into the G-buffer, in place, over the screen tiles that hold one.
369
371
  *
370
372
  * **Every channel is composited exactly, in registers.** Nothing is blended by hardware and nothing
371
373
  * is approximated: two of the four targets are integer formats that cannot blend at all, and the
372
374
  * previous shading normal and the ambient in the albedo's alpha both have to survive — which they
373
- * only can if the pass reads one texture and writes another (D23).
375
+ * only can if the pass reads one texture and writes another (D23). The one it reads is
376
+ * `shader_decal_tile_copy`'s copy of the same tiles, so only the covered part of the screen
377
+ * is read and written twice, rather than all of it once.
374
378
  *
375
379
  * The face normal is carried through untouched. A decal changes what a surface looks like, not which
376
380
  * way it is turned, and the face normal is what the fade and everything downstream reason about.
377
381
  *
378
- * @type {ImageShader}
382
+ * @type {DecalTileShader}
379
383
  */
380
- export const shader_decal_composite = ImageShader.from({
384
+ export const shader_decal_composite = new DecalTileShader({
381
385
  descriptor: ShaderDescriptor.from({
382
386
  label: "Decal composite",
383
387
  resources,
@@ -0,0 +1,12 @@
1
+ export const DECAL_TILE_COPY_SETTINGS: WebGPUStruct;
2
+ /**
3
+ * Copies the G-buffer under the tiles that hold a decal, so the composite can read a surface as it
4
+ * was while writing the same texels in place — one texture cannot be a render attachment and a
5
+ * sampled source in one pass, and two of the four targets are integers that cannot blend.
6
+ *
7
+ * @type {DecalTileShader}
8
+ */
9
+ export const shader_decal_tile_copy: DecalTileShader;
10
+ import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
11
+ import { DecalTileShader } from "./DecalTileShader.js";
12
+ //# sourceMappingURL=shader_decal_tile_copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_decal_tile_copy.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_decal_tile_copy.js"],"names":[],"mappings":"AAWA,oDAEG;AA6CH;;;;;;GAMG;AACH,qCAFU,eAAe,CActB;6BArE0B,qDAAqD;gCAClD,sBAAsB"}
@@ -0,0 +1,78 @@
1
+ import { G_BUFFER_ALBEDO_FORMAT } from "../../../shade/renderer/gbuffer/G_BUFFER_ALBEDO_FORMAT.js";
2
+ import { CodeChunk } from "../../../shade/renderer/shader/compiler/CodeChunk.js";
3
+ import {
4
+ ShaderResourceSetDescriptor
5
+ } from "../../../shade/renderer/shader/resource/ShaderResourceSetDescriptor.js";
6
+ import { ShaderDescriptor } from "../../../shade/renderer/shader/ShaderDescriptor.js";
7
+ import { vec2u } from "../../../shade/renderer/shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
8
+ import { WebGPUArray } from "../../../shade/renderer/shader/type/WebGPUArray.js";
9
+ import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
10
+ import { DecalTileShader } from "./DecalTileShader.js";
11
+
12
+ export const DECAL_TILE_COPY_SETTINGS = WebGPUStruct.from({
13
+ screen_resolution: vec2u,
14
+ });
15
+
16
+ const resources = new ShaderResourceSetDescriptor();
17
+
18
+ resources.setImmediate("settings", DECAL_TILE_COPY_SETTINGS);
19
+
20
+ resources.createGroup()
21
+ .addStorageBuffer("decal_tiles", WebGPUArray.u32);
22
+
23
+ // integer targets are read as integer textures, as the composite reads them — see its note
24
+ resources.createGroup()
25
+ .addTexture("gBufferPBR")
26
+ .addTexture("gBufferNormal", "uint")
27
+ .addTexture("gBufferAlbedo")
28
+ .addTexture("gBufferEmissive", "uint");
29
+
30
+ const body = CodeChunk.from(
31
+ //language=WGSL
32
+ `
33
+ struct DecalTileCopyOut {
34
+ @location(0) pbr : vec2<f32>,
35
+ @location(1) normal : vec4<u32>,
36
+ @location(2) albedo : vec4<f32>,
37
+ @location(3) emissive : u32,
38
+ }
39
+
40
+ @fragment
41
+ fn main(
42
+ @builtin(position) coord : vec4<f32>,
43
+ ) -> DecalTileCopyOut {
44
+ let i_coord = vec2<i32>(coord.xy);
45
+
46
+ var out : DecalTileCopyOut;
47
+
48
+ // the two unorm targets round-trip exactly: k/255 written back is k
49
+ out.pbr = textureLoad(gBufferPBR, i_coord, 0).rg;
50
+ out.normal = textureLoad(gBufferNormal, i_coord, 0);
51
+ out.albedo = textureLoad(gBufferAlbedo, i_coord, 0);
52
+ out.emissive = textureLoad(gBufferEmissive, i_coord, 0).r;
53
+
54
+ return out;
55
+ }
56
+ `
57
+ );
58
+
59
+ /**
60
+ * Copies the G-buffer under the tiles that hold a decal, so the composite can read a surface as it
61
+ * was while writing the same texels in place — one texture cannot be a render attachment and a
62
+ * sampled source in one pass, and two of the four targets are integers that cannot blend.
63
+ *
64
+ * @type {DecalTileShader}
65
+ */
66
+ export const shader_decal_tile_copy = new DecalTileShader({
67
+ descriptor: ShaderDescriptor.from({
68
+ label: "Decal tiles / copy",
69
+ resources,
70
+ body
71
+ }),
72
+ targets: [
73
+ { format: "rg8unorm" },
74
+ { format: "rgba16uint" },
75
+ { format: G_BUFFER_ALBEDO_FORMAT },
76
+ { format: "r32uint" },
77
+ ]
78
+ });
@@ -0,0 +1,11 @@
1
+ export const DECAL_TILE_GATHER_SETTINGS: WebGPUStruct;
2
+ /**
3
+ * Lists the screen tiles whose froxel column holds at least one decal — the only part of the screen
4
+ * the decal passes draw. The list's first word is its length, and is zero when the pass starts.
5
+ *
6
+ * @type {ComputeShader}
7
+ */
8
+ export const shader_gather_decal_tiles: ComputeShader;
9
+ import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
10
+ import { ComputeShader } from "../../../shade/renderer/shader/ComputeShader.js";
11
+ //# sourceMappingURL=shader_gather_decal_tiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader_gather_decal_tiles.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/decal/shader_gather_decal_tiles.js"],"names":[],"mappings":"AAcA,sDAEG;AAqDH;;;;;GAKG;AACH,wCAFU,aAAa,CAMpB;6BApE0B,qDAAqD;8BANpD,iDAAiD"}
@@ -0,0 +1,80 @@
1
+ import {
2
+ chunk_light_cluster_resolution_xy_from_screen
3
+ } from "../../../shade/renderer/light/cluster/chunk_light_cluster_resolution_xy_from_screen.js";
4
+ import { chunk_grid3d_to_index } from "../../../shade/renderer/shader/chunk/grid/chunk_grid3d_to_index.js";
5
+ import { CodeChunk } from "../../../shade/renderer/shader/compiler/CodeChunk.js";
6
+ import { ComputeShader } from "../../../shade/renderer/shader/ComputeShader.js";
7
+ import {
8
+ ShaderResourceSetDescriptor
9
+ } from "../../../shade/renderer/shader/resource/ShaderResourceSetDescriptor.js";
10
+ import { atomic_u32, vec2u } from "../../../shade/renderer/shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
11
+ import { WebGPUArray } from "../../../shade/renderer/shader/type/WebGPUArray.js";
12
+ import { WebGPUStruct } from "../../../shade/renderer/shader/type/WebGPUStruct.js";
13
+ import { DECAL_CLUSTER_METADATA, DECAL_CLUSTER_RESOLUTION_Z } from "./DECAL_CLUSTER.js";
14
+
15
+ export const DECAL_TILE_GATHER_SETTINGS = WebGPUStruct.from({
16
+ screen_resolution: vec2u,
17
+ });
18
+
19
+ const resources = new ShaderResourceSetDescriptor();
20
+
21
+ resources.setImmediate("settings", DECAL_TILE_GATHER_SETTINGS);
22
+
23
+ resources.createGroup()
24
+ .addStorageBuffer("cluster_lookup", WebGPUArray.from(DECAL_CLUSTER_METADATA))
25
+ .addStorageBuffer("decal_tiles", WebGPUArray.from(atomic_u32), true);
26
+
27
+ const body = CodeChunk.from(
28
+ //language=WGSL
29
+ `
30
+ @compute @workgroup_size(8, 8, 1)
31
+ fn main(
32
+ @builtin(global_invocation_id) tile : vec3<u32>
33
+ ) {
34
+ let resolution = light_cluster_resolution_xy_from_screen(settings.screen_resolution);
35
+
36
+ if (any(tile.xy >= resolution)) {
37
+ return;
38
+ }
39
+
40
+ /*
41
+ Gathered per tile, down its own column, rather than scattered by the froxels that hold a decal:
42
+ a tile is listed once however many of its slices are occupied, with no flag to clear and no
43
+ second pass to compact one.
44
+ */
45
+ var occupied = false;
46
+
47
+ for (var z = 0u; z < ${DECAL_CLUSTER_RESOLUTION_Z}u; z++) {
48
+ if (cluster_lookup[grid3d_to_index(vec3<u32>(tile.xy, z), resolution)].count > 0u) {
49
+ occupied = true;
50
+ break;
51
+ }
52
+ }
53
+
54
+ if (!occupied) {
55
+ return;
56
+ }
57
+
58
+ // the count leads the list; the list is sized for every tile, so the append cannot overrun
59
+ let slot = atomicAdd(&decal_tiles[0], 1u);
60
+
61
+ atomicStore(&decal_tiles[1u + slot], tile.x | (tile.y << 16u));
62
+ }
63
+ `,
64
+ [
65
+ chunk_light_cluster_resolution_xy_from_screen,
66
+ chunk_grid3d_to_index,
67
+ ]
68
+ );
69
+
70
+ /**
71
+ * Lists the screen tiles whose froxel column holds at least one decal — the only part of the screen
72
+ * the decal passes draw. The list's first word is its length, and is zero when the pass starts.
73
+ *
74
+ * @type {ComputeShader}
75
+ */
76
+ export const shader_gather_decal_tiles = ComputeShader.from({
77
+ label: "decal tiles / gather",
78
+ resources,
79
+ body
80
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Bits of {@link MouseEvent.buttons }, the set of buttons held during an event.
3
+ *
4
+ * NOTE: not the {@link MouseButtons } ordinals, which index a single button by {@link MouseEvent.button }
5
+ * and put the middle button before the right one. Here the right button is 2 and the middle one 4.
6
+ */
7
+ export type MouseEventButtons = number;
8
+ export namespace MouseEventButtons {
9
+ let primary: number;
10
+ let secondary: number;
11
+ let auxiliary: number;
12
+ }
13
+ //# sourceMappingURL=MouseEventButtons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MouseEventButtons.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/input/devices/mouse/MouseEventButtons.js"],"names":[],"mappings":";;;;;;gCAOU,MAAM"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bits of {@link MouseEvent.buttons}, the set of buttons held during an event.
3
+ *
4
+ * NOTE: not the {@link MouseButtons} ordinals, which index a single button by {@link MouseEvent.button}
5
+ * and put the middle button before the right one. Here the right button is 2 and the middle one 4.
6
+ *
7
+ * @readonly
8
+ * @enum {number}
9
+ */
10
+ export const MouseEventButtons = {
11
+ /**
12
+ * usually the left button, and a touch or pen in contact
13
+ */
14
+ primary: 1,
15
+ /**
16
+ * usually the right button
17
+ */
18
+ secondary: 2,
19
+ /**
20
+ * usually the middle button or the wheel
21
+ */
22
+ auxiliary: 4,
23
+ };
@@ -1,4 +1,8 @@
1
1
  export default KeyboardCameraController;
2
+ /**
3
+ * WASD and the arrow keys move a top-down camera's orbit target across the ground, along the way the
4
+ * view is turned, at a fixed speed in world units a second.
5
+ */
2
6
  declare class KeyboardCameraController {
3
7
  /**
4
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"KeyboardCameraController.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/input/ecs/controllers/KeyboardCameraController.js"],"names":[],"mappings":";AAaA;IACI;;;;;OAKG;IACH,8BAHW;QAAC,SAAS,0BAAyB;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,+BAqG7D;IALG,gBAIgB;IAGpB;;OAEG;IACH,0CAEC;CACJ;mBAvHkB,wBAAwB"}
1
+ {"version":3,"file":"KeyboardCameraController.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/input/ecs/controllers/KeyboardCameraController.js"],"names":[],"mappings":";AAQA;;;GAGG;AACH;IACI;;;;;OAKG;IACH,8BAHW;QAAC,SAAS,0BAAyB;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,+BAkE7D;IALG,gBAIgB;IAGpB;;OAEG;IACH,0CAEC;CACJ;mBAtFkB,wBAAwB"}
@@ -1,16 +1,15 @@
1
1
  import { assert } from "../../../../core/assert.js";
2
- import Vector2 from '../../../../core/geom/Vector2.js';
3
- import Vector3 from "../../../../core/geom/Vector3.js";
4
- import { v3_quaternion_apply } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
5
2
  import Script from '../../../ecs/components/Script.js';
6
3
  import { SerializationMetadata } from "../../../ecs/components/SerializationMetadata.js";
7
4
  import { Tag } from "../../../ecs/components/Tag.js";
8
5
  import Entity from '../../../ecs/Entity.js';
9
- import { Transform64 } from "../../../ecs/transform/Transform64.js";
6
+ import { top_down_truck_on_ground } from "../../../graphics/ecs/camera/topdown/TopDownCameraController.js";
10
7
  import InputController from '../components/InputController.js';
11
8
 
12
- const v3 = new Vector3();
13
-
9
+ /**
10
+ * WASD and the arrow keys move a top-down camera's orbit target across the ground, along the way the
11
+ * view is turned, at a fixed speed in world units a second.
12
+ */
14
13
  class KeyboardCameraController {
15
14
  /**
16
15
  *
@@ -23,8 +22,6 @@ class KeyboardCameraController {
23
22
 
24
23
  assert.notEqual(controller, undefined, 'controller is undefined');
25
24
 
26
- const cameraPanSpeed = new Vector2(0, 0);
27
-
28
25
  const controls = {
29
26
  panUp: false,
30
27
  panDown: false,
@@ -70,43 +67,10 @@ class KeyboardCameraController {
70
67
  inputController.on.unlinked.add(clearControls);
71
68
 
72
69
  const script = new Script(function (timeDelta) {
73
- cameraPanSpeed.set(0, 0);
74
-
75
- if (controls.panDown) {
76
- cameraPanSpeed.y += 1;
77
- }
78
- if (controls.panUp) {
79
- cameraPanSpeed.y -= 1;
80
- }
81
- if (controls.panLeft) {
82
- cameraPanSpeed.x -= 1;
83
- }
84
- if (controls.panRight) {
85
- cameraPanSpeed.x += 1;
86
- }
87
-
88
- if (cameraPanSpeed.isZero()) {
89
- // not panning
90
- return;
91
- }
92
-
93
- const displacement = cameraPanSpeed.clone().multiplyScalar(keyboardPanSpeed * timeDelta);
94
-
95
- const camera_transform = ecd.getComponent(cameraController.entity, Transform64);
96
-
97
- // by component: a Transform64's `rotation` is four numbers in an array, and
98
- // `applyQuaternion` reads `.x` off what it is given
99
- v3_quaternion_apply(
100
- v3, 0,
101
- -displacement.x, 0, -displacement.y,
102
- camera_transform.rotation_x,
103
- camera_transform.rotation_y,
104
- camera_transform.rotation_z,
105
- camera_transform.rotation_w
106
- );
107
-
108
-
109
- controller.target.add(v3);
70
+ const right = (controls.panRight ? 1 : 0) - (controls.panLeft ? 1 : 0);
71
+ const forward = (controls.panUp ? 1 : 0) - (controls.panDown ? 1 : 0);
72
+
73
+ top_down_truck_on_ground(controller, right, forward, keyboardPanSpeed * timeDelta);
110
74
  });
111
75
 
112
76
  const builder = new Entity();
@@ -66,11 +66,11 @@ export class FluidObstacleSystem extends System<any> {
66
66
  /**
67
67
  * @param {FluidComponent} fluid
68
68
  */
69
- static "__#478@#refresh_masks"(fluid: FluidComponent): void;
69
+ static "__#481@#refresh_masks"(fluid: FluidComponent): void;
70
70
  /**
71
71
  * @param {FluidComponent} fluid
72
72
  */
73
- static "__#478@#clear_field"(fluid: FluidComponent): void;
73
+ static "__#481@#clear_field"(fluid: FluidComponent): void;
74
74
  /**
75
75
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
76
76
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -82,7 +82,7 @@ export class FluidObstacleSystem extends System<any> {
82
82
  * @param {number} inflation world-units SDF threshold
83
83
  * @param {Float64Array} point length-3 scratch
84
84
  */
85
- static "__#478@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
85
+ static "__#481@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
86
86
  /**
87
87
  * Write the obstacle's translation velocity onto every face of every cell
88
88
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -102,7 +102,7 @@ export class FluidObstacleSystem extends System<any> {
102
102
  * @param {number} wvy
103
103
  * @param {number} wvz
104
104
  */
105
- static "__#478@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
105
+ static "__#481@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
106
106
  constructor();
107
107
  dependencies: (typeof FluidObstacle)[];
108
108
  components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof FluidObstacle> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof FluidComponent>)[];