@woosh/meep-engine 3.26.0 → 3.27.0

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 (236) hide show
  1. package/package.json +1 -1
  2. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +542 -0
  3. package/src/core/binary/lz4/LZ4_LEVEL.d.ts +33 -0
  4. package/src/core/binary/lz4/LZ4_LEVEL.d.ts.map +1 -0
  5. package/src/core/binary/lz4/LZ4_LEVEL.js +32 -0
  6. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts +33 -0
  7. package/src/core/binary/lz4/lz4_compress_block_at_level.d.ts.map +1 -0
  8. package/src/core/binary/lz4/lz4_compress_block_at_level.js +47 -0
  9. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts +40 -0
  10. package/src/core/binary/lz4/lz4_compress_block_hc.d.ts.map +1 -0
  11. package/src/core/binary/lz4/lz4_compress_block_hc.js +1382 -0
  12. package/src/core/binary/lz4/lz4_decompress_block.d.ts +2 -1
  13. package/src/core/binary/lz4/lz4_decompress_block.d.ts.map +1 -1
  14. package/src/core/binary/lz4/lz4_decompress_block.js +31 -6
  15. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +14 -7
  16. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  17. package/src/core/geom/3d/shape/HeightMapShape3D.js +87 -78
  18. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  19. package/src/shade/playground/vgeo_runtime/README.md +167 -22
  20. package/src/shade/playground/vgeo_runtime/index.html +112 -62
  21. package/src/shade/playground/vgeo_runtime/main.js +660 -83
  22. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +1 -1
  23. package/src/shade/playground/vgeo_viewer/sample_asset.js +19 -2
  24. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +11 -0
  25. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  26. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +16 -8
  27. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  28. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +16 -11
  29. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +73 -5
  30. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +26 -15
  31. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +5 -3
  32. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +18 -0
  33. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  34. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +20 -0
  35. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +1 -1
  36. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +56 -9
  37. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  38. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +1 -0
  39. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +22 -0
  40. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  41. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +24 -0
  42. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +12 -0
  43. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  44. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +13 -0
  45. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +8 -1
  46. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  47. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +11 -3
  48. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +9 -0
  49. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  50. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +10 -1
  51. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts +18 -0
  52. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.d.ts.map +1 -0
  53. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_ENTRY_COUNT.js +17 -0
  54. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts +8 -0
  55. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.d.ts.map +1 -0
  56. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_PARENT_REF.js +7 -0
  57. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +3 -0
  58. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -0
  59. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts +14 -0
  60. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.d.ts.map +1 -0
  61. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_ENTRY_SIZE.js +13 -0
  62. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts +11 -0
  63. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.d.ts.map +1 -0
  64. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js +10 -0
  65. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +20 -0
  66. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  67. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +20 -2
  68. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts +4 -0
  69. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.d.ts.map +1 -1
  70. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerHeader.js +4 -0
  71. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +29 -3
  72. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  73. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +81 -122
  74. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +40 -0
  75. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +44 -0
  77. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +69 -0
  78. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +236 -0
  80. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +14 -0
  81. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  82. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +15 -0
  83. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts +31 -0
  84. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.d.ts.map +1 -0
  85. package/src/shade/renderer/geometry/virtual/format/read/vgeo_byte_source_from_descriptor.js +32 -0
  86. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +10 -0
  87. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  88. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +21 -1
  89. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts +15 -0
  90. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.d.ts.map +1 -0
  91. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_transfer.js +84 -0
  92. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts +22 -0
  93. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -0
  94. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +96 -0
  95. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  96. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +55 -0
  97. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  98. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +202 -13
  99. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  100. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +147 -10
  101. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +637 -0
  102. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts +33 -36
  103. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.d.ts.map +1 -1
  104. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryPool.js +109 -193
  105. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +58 -28
  106. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  107. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +77 -105
  108. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +37 -0
  109. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +105 -22
  110. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +548 -0
  111. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +29 -50
  112. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  113. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +47 -489
  114. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts +84 -0
  115. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -0
  116. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +393 -0
  117. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts +234 -0
  118. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -0
  119. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +1363 -0
  120. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts +81 -0
  121. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidencyOptions.js +89 -0
  123. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts +53 -34
  124. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +407 -124
  126. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +100 -0
  127. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -0
  128. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +219 -0
  129. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts +17 -0
  130. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.d.ts.map +1 -0
  131. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_EXPAND.js +47 -0
  132. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts +20 -0
  133. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.d.ts.map +1 -0
  134. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_FLAG_COARSEN.js +19 -0
  135. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.d.ts.map +1 -1
  136. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_PARAMS_STRUCT.js +30 -12
  137. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  138. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +15 -0
  139. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +18 -1
  141. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.d.ts.map +1 -1
  142. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_prepare.js +5 -15
  143. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts +3 -0
  144. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_queue_remainder.js +77 -0
  146. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts +3 -0
  147. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -0
  148. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +186 -0
  149. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  150. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +20 -8
  151. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  152. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +580 -188
  153. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts +15 -18
  154. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/runtime/cut/vgeo_cut_feedback_layout.js +19 -28
  156. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  157. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +45 -25
  158. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  159. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +11 -0
  160. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  161. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.d.ts +0 -1
  162. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_FEEDBACK_OFFSET.js +12 -10
  163. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.d.ts +1 -0
  164. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_OFFSET.js +8 -0
  165. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts +7 -2
  166. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.d.ts.map +1 -1
  167. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_GROUP_ROW_WORDS.js +8 -3
  168. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.d.ts +2 -0
  169. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_OFFSET.js +19 -0
  170. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.d.ts.map +1 -1
  171. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PAGE_ROW_WORDS.js +1 -1
  172. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts +5 -0
  173. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.d.ts.map +1 -0
  174. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_OFFSET.js +22 -0
  175. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts +14 -0
  176. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.d.ts.map +1 -0
  177. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_PARENT_ROW_WORDS.js +13 -0
  178. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts +17 -0
  179. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.d.ts.map +1 -0
  180. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_QUEUE_TARGET_PARENT_BIT.js +16 -0
  181. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts +15 -0
  182. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.d.ts.map +1 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/make_vgeo_page_worker.js +16 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts +23 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.d.ts.map +1 -0
  186. package/src/shade/renderer/geometry/virtual/runtime/vgeo_frontier_words.js +28 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts +2 -0
  188. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.d.ts.map +1 -0
  189. package/src/shade/renderer/geometry/virtual/runtime/vgeo_page.worker.js +13 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts +10 -5
  191. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.d.ts.map +1 -1
  192. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_block_words.js +15 -6
  193. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts +6 -1
  194. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  195. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +38 -1
  196. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  197. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +4 -3
  198. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  199. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  200. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +6 -3
  201. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  202. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +6 -3
  203. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  204. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  205. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +12 -4
  206. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +2 -0
  207. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  208. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +58 -57
  209. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  210. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +3 -5
  211. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  212. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +3 -4
  213. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  214. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -4
  215. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  216. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +7 -7
  217. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  218. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +83 -78
  219. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  220. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +7 -1
  221. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  222. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +7 -1
  223. package/src/shade/renderer/scene/GPUSceneContext.d.ts +22 -2
  224. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  225. package/src/shade/renderer/scene/GPUSceneContext.js +59 -4
  226. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  227. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +92 -16
  228. package/src/shade/renderer/view/GPUViewContext.d.ts +5 -0
  229. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  230. package/src/shade/renderer/view/GPUViewContext.js +21 -0
  231. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  232. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +74 -3
  233. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +0 -723
  234. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +0 -50
  235. package/src/shade/renderer/shader/chunk/jobs/NOTES.md +0 -47
  236. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.js +0 -102
@@ -6,7 +6,8 @@
6
6
  * its low nibble the match length less four; either saturates at fifteen and continues in whole
7
7
  * bytes, a 255 meaning "and more". The match's distance is a 16-bit little-endian offset back from
8
8
  * the write head, and it is allowed to reach into bytes this same sequence is producing — that
9
- * overlap is how the format codes runs, so the copy has to go a byte at a time.
9
+ * overlap is how the format codes runs, so a match that reaches back less far than it is long is
10
+ * copied a byte at a time.
10
11
  *
11
12
  * Blocks here are independent: a match reaches back no further than `destination_offset`, never
12
13
  * into whatever a previous block left in the buffer. That is what `LZ4_compress_default` produces
@@ -1 +1 @@
1
- {"version":3,"file":"lz4_decompress_block.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/lz4/lz4_decompress_block.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,kDATW,UAAU,sBACV,MAAM,mBACN,MAAM,UACN,UAAU,iBACV,MAAM,cACN,MAAM,GACJ,MAAM,CA8GlB"}
1
+ {"version":3,"file":"lz4_decompress_block.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/lz4/lz4_decompress_block.js"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,kDATW,UAAU,sBACV,MAAM,mBACN,MAAM,UACN,UAAU,iBACV,MAAM,cACN,MAAM,GACJ,MAAM,CAyHlB"}
@@ -1,5 +1,18 @@
1
1
  import { assert } from "../../assert.js";
2
2
 
3
+ /**
4
+ * Runs shorter than this are cheaper to copy a byte at a time than to hand to `set` or
5
+ * `copyWithin`, whose call overhead dominates until there is a memmove's worth of work behind it.
6
+ * Both halves earn their keep, and on real geometry it is the literals that carry the win: four
7
+ * fifths of a decoded `.vgeo` page arrives as literal runs of about thirty-five bytes, while its
8
+ * matches average nine and stay in the loop whatever this is set to.
9
+ *
10
+ * Swept on 2,267 real pages at both block shapes. The top of the curve is broad — anything from
11
+ * sixteen up is most of the win — and this is where it sits, which is also where
12
+ * {@link lz4_compress_block} put its own, arrived at separately and on literals alone.
13
+ */
14
+ const BULK_COPY_LENGTH = 32;
15
+
3
16
  /**
4
17
  * Decode one LZ4 block.
5
18
  *
@@ -8,7 +21,8 @@ import { assert } from "../../assert.js";
8
21
  * its low nibble the match length less four; either saturates at fifteen and continues in whole
9
22
  * bytes, a 255 meaning "and more". The match's distance is a 16-bit little-endian offset back from
10
23
  * the write head, and it is allowed to reach into bytes this same sequence is producing — that
11
- * overlap is how the format codes runs, so the copy has to go a byte at a time.
24
+ * overlap is how the format codes runs, so a match that reaches back less far than it is long is
25
+ * copied a byte at a time.
12
26
  *
13
27
  * Blocks here are independent: a match reaches back no further than `destination_offset`, never
14
28
  * into whatever a previous block left in the buffer. That is what `LZ4_compress_default` produces
@@ -72,8 +86,12 @@ export function lz4_decompress_block(destination, destination_offset, destinatio
72
86
  );
73
87
  }
74
88
 
75
- for (let i = 0; i < literal_length; i++) {
76
- destination[d + i] = source[s + i];
89
+ if (literal_length >= BULK_COPY_LENGTH) {
90
+ destination.set(source.subarray(s, s + literal_length), d);
91
+ } else {
92
+ for (let i = 0; i < literal_length; i++) {
93
+ destination[d + i] = source[s + i];
94
+ }
77
95
  }
78
96
 
79
97
  d += literal_length;
@@ -127,9 +145,16 @@ export function lz4_decompress_block(destination, destination_offset, destinatio
127
145
  );
128
146
  }
129
147
 
130
- // a byte at a time: the match is allowed to overlap what it is writing, which is how runs are coded
131
- for (let i = 0; i < match_length; i++) {
132
- destination[d + i] = destination[match_position + i];
148
+ // A match that does not reach back as far as it is long overlaps the bytes it is writing, and
149
+ // that is how the format codes runs: `copyWithin` moves as if through a temporary, so it
150
+ // would lay down one copy of the pattern where the format means it to repeat. Only a match
151
+ // clear of its own output can take it, and the byte loop below is the run.
152
+ if (match_length >= BULK_COPY_LENGTH && match_offset >= match_length) {
153
+ destination.copyWithin(d, match_position, match_position + match_length);
154
+ } else {
155
+ for (let i = 0; i < match_length; i++) {
156
+ destination[d + i] = destination[match_position + i];
157
+ }
133
158
  }
134
159
 
135
160
  d += match_length;
@@ -184,13 +184,20 @@ export class HeightMapShape3D extends AbstractShape3D {
184
184
  * (the shared {@link tri3_raycast} convention). A cast from below the terrain
185
185
  * therefore reports a downward normal, not the surface's true upward one.
186
186
  *
187
- * A hit landing exactly ON a sub-cell boundary gets the normal of one of the
188
- * facets meeting there, and which one follows from traversal order: this walks
189
- * the grid along the ray, the narrowphase enumerates it row-major, so on a grid
190
- * line — and especially a grid corner, where four facets meet — the two can
191
- * name different facets. The hit POINT still agrees; a faceted surface simply
192
- * has no single normal at a seam. Measure-zero, and called out because it is
193
- * the only place the two answers part company.
187
+ * A hit landing exactly ON a seam between facets gets the normal of one of the
188
+ * facets meeting there. INSIDE a sub-cell the two paths agree — they split on
189
+ * the same D–B diagonal and break the resulting tie in favour of the same
190
+ * facet — which matters because that diagonal runs through the sub-cell's
191
+ * centre, so a cast down the middle of a cell lands on it routinely rather
192
+ * than exceptionally.
193
+ *
194
+ * BETWEEN sub-cells they can differ, and which facet each names follows from
195
+ * traversal order: this walks the grid along the ray, the narrowphase
196
+ * enumerates it row-major, so on a grid line — and especially a grid corner,
197
+ * where four facets meet — the two can name different facets. The hit POINT
198
+ * still agrees; a faceted surface simply has no single normal at a seam.
199
+ * Measure-zero, and called out because it is the only place the two answers
200
+ * part company.
194
201
  *
195
202
  * `size.y` does NOT bound the query. Sampler values are not clamped to it (see
196
203
  * the class docstring), so clipping the ray to the height range that
@@ -1 +1 @@
1
- {"version":3,"file":"HeightMapShape3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/HeightMapShape3D.js"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IA4DI;;;;;;;;;;;OAWG;IACH,wCATW,MAAM,UACN,MAAM,UACN,MAAM,gBACN,OAAO,iBACP,MAAM,GAGJ,gBAAgB,CAqB5B;IA1FD;;;;;OAKG;IACH,sBAFU,OAAO,CAEkB;IAEnC;;;;;;;OAOG;IACH,eAFU,OAAO,CAEW;IAE5B;;;;;OAKG;IACH,SAFU,YAAY,IAAI,CAEX;IAEf;;;;;;;;;;;;;;;;OAgBG;IACH,cAFU,MAAM,CAEC;IAEjB;;;;;OAKG;IACH,eAA6B;IAG7B,6BAA2B;IAE3B,6BAA2B;IAC3B,6BAA2B;IAmC3B;;;;;;;;;OASG;IACH,sBA+CC;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,8BALW,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAelB;IAED,wCA8BC;IAED,oCA2BC;IAED;;;;;;;;OAQG;IACH,6CAmBC;IAED;;;;OAIG;IACH,4DA2BC;IAED;;;;;;;;;OASG;IACH,qGAEC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyDG;IACH,aAJW,YAAY,GAAC,MAAM,EAAE,cAEnB,OAAO,CAyNnB;IAED,kFAiBC;IA6CD;;;OAGG;IACH,cAHW,gBAAgB,GACd,OAAO,CAUnB;IAWL;;;;;;OAMG;IACH,6BAFU,OAAO,CAE4B;CAT5C;gCA5tB+B,sBAAsB;wBAD9B,kBAAkB"}
1
+ {"version":3,"file":"HeightMapShape3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/HeightMapShape3D.js"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IA4DI;;;;;;;;;;;OAWG;IACH,wCATW,MAAM,UACN,MAAM,UACN,MAAM,gBACN,OAAO,iBACP,MAAM,GAGJ,gBAAgB,CAqB5B;IA1FD;;;;;OAKG;IACH,sBAFU,OAAO,CAEkB;IAEnC;;;;;;;OAOG;IACH,eAFU,OAAO,CAEW;IAE5B;;;;;OAKG;IACH,SAFU,YAAY,IAAI,CAEX;IAEf;;;;;;;;;;;;;;;;OAgBG;IACH,cAFU,MAAM,CAEC;IAEjB;;;;;OAKG;IACH,eAA6B;IAG7B,6BAA2B;IAE3B,6BAA2B;IAC3B,6BAA2B;IAmC3B;;;;;;;;;OASG;IACH,sBA8CC;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,8BALW,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAelB;IAED,wCA6BC;IAED,oCA2BC;IAED;;;;;;;;OAQG;IACH,6CAmBC;IAED;;;;OAIG;IACH,4DA2BC;IAED;;;;;;;;;OASG;IACH,qGAEC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgEG;IACH,aAJW,YAAY,GAAC,MAAM,EAAE,cAEnB,OAAO,CA0NnB;IAED,kFAiBC;IA6CD;;;OAGG;IACH,cAHW,gBAAgB,GACd,OAAO,CAUnB;IAWL;;;;;;OAMG;IACH,6BAFU,OAAO,CAE4B;CAT5C;gCAluB+B,sBAAsB;wBAD9B,kBAAkB"}
@@ -2,9 +2,12 @@ import { hash_mix3 } from "../../../math/hash/hash_mix3.js";
2
2
  import { hash_mix2 } from "../../../math/hash/hash_mix2.js";
3
3
  import { assert } from "../../../assert.js";
4
4
  import { clamp } from "../../../math/clamp.js";
5
+ import { clamp_index } from "../../../math/clamp_index.js";
5
6
  import { optional_equality } from "../../../model/object/optional_equality.js";
6
7
  import { optional_hash } from "../../../model/object/optional_hash.js";
7
8
  import { tri3_raycast } from "../triangle/tri3_raycast.js";
9
+ import { v3_cross } from "../../vec3/v3_cross.js";
10
+ import { v3_dot } from "../../vec3/v3_dot.js";
8
11
  import { v3_length } from "../../vec3/v3_length.js";
9
12
  import { Vector3 } from "../../Vector3.js";
10
13
  import { AbstractShape3D } from "./AbstractShape3D.js";
@@ -192,14 +195,13 @@ export class HeightMapShape3D extends AbstractShape3D {
192
195
  u_y *= u_inv;
193
196
  u_z *= u_inv;
194
197
 
195
- // v = u × n (for n=+Y, u=+X this gives v=+Z, the intuitive choice)
196
- const v_x = u_y * nz - u_z * ny;
197
- const v_y = u_z * nx - u_x * nz;
198
- const v_z = u_x * ny - u_y * nx;
199
-
200
198
  const b = this._basis;
199
+
201
200
  b[0] = u_x; b[1] = u_y; b[2] = u_z;
202
- b[3] = v_x; b[4] = v_y; b[5] = v_z;
201
+
202
+ // v = u × n (for n=+Y, u=+X this gives v=+Z, the intuitive choice)
203
+ v3_cross(b, 3, u_x, u_y, u_z, nx, ny, nz);
204
+
203
205
  b[6] = nx; b[7] = ny; b[8] = nz;
204
206
 
205
207
  this._basis_orientation_x = nx;
@@ -233,8 +235,8 @@ export class HeightMapShape3D extends AbstractShape3D {
233
235
  const b = this._basis;
234
236
 
235
237
  // project onto basis u and basis v
236
- const u_coord = b[0] * px + b[1] * py + b[2] * pz;
237
- const v_coord = b[3] * px + b[4] * py + b[5] * pz;
238
+ const u_coord = v3_dot(b[0], b[1], b[2], px, py, pz);
239
+ const v_coord = v3_dot(b[3], b[4], b[5], px, py, pz);
238
240
 
239
241
  const u01 = u_coord / this.size[0] + 0.5;
240
242
  const v01 = v_coord / this.size[2] + 0.5;
@@ -266,11 +268,10 @@ export class HeightMapShape3D extends AbstractShape3D {
266
268
 
267
269
  const uv_extent = Math.abs(cu) * half_u + Math.abs(cv) * half_v;
268
270
 
269
- const h_lo = ch < 0 ? ch * sy : 0;
270
- const h_hi = ch > 0 ? ch * sy : 0;
271
+ const h_extent = ch * sy;
271
272
 
272
- result[k] = -uv_extent + h_lo;
273
- result[k + 3] = uv_extent + h_hi;
273
+ result[k] = -uv_extent + Math.min(h_extent, 0);
274
+ result[k + 3] = uv_extent + Math.max(h_extent, 0);
274
275
  }
275
276
  }
276
277
 
@@ -284,9 +285,9 @@ export class HeightMapShape3D extends AbstractShape3D {
284
285
  const b = this._basis;
285
286
 
286
287
  // project into heightmap-local frame (u, v, h)
287
- const u_coord = b[0] * px + b[1] * py + b[2] * pz;
288
- const v_coord = b[3] * px + b[4] * py + b[5] * pz;
289
- const h_coord = b[6] * px + b[7] * py + b[8] * pz;
288
+ const u_coord = v3_dot(b[0], b[1], b[2], px, py, pz);
289
+ const v_coord = v3_dot(b[3], b[4], b[5], px, py, pz);
290
+ const h_coord = v3_dot(b[6], b[7], b[8], px, py, pz);
290
291
 
291
292
  const half_u = this.size[0] * 0.5;
292
293
  const half_v = this.size[2] * 0.5;
@@ -321,9 +322,9 @@ export class HeightMapShape3D extends AbstractShape3D {
321
322
 
322
323
  const b = this._basis;
323
324
 
324
- const u_coord = b[0] * px + b[1] * py + b[2] * pz;
325
- const v_coord = b[3] * px + b[4] * py + b[5] * pz;
326
- const h_coord = b[6] * px + b[7] * py + b[8] * pz;
325
+ const u_coord = v3_dot(b[0], b[1], b[2], px, py, pz);
326
+ const v_coord = v3_dot(b[3], b[4], b[5], px, py, pz);
327
+ const h_coord = v3_dot(b[6], b[7], b[8], px, py, pz);
327
328
 
328
329
  const u01 = u_coord / this.size[0] + 0.5;
329
330
  const v01 = v_coord / this.size[2] + 0.5;
@@ -347,8 +348,8 @@ export class HeightMapShape3D extends AbstractShape3D {
347
348
 
348
349
  const b = this._basis;
349
350
 
350
- const u_coord = b[0] * rx + b[1] * ry + b[2] * rz;
351
- const v_coord = b[3] * rx + b[4] * ry + b[5] * rz;
351
+ const u_coord = v3_dot(b[0], b[1], b[2], rx, ry, rz);
352
+ const v_coord = v3_dot(b[3], b[4], b[5], rx, ry, rz);
352
353
 
353
354
  const half_u = this.size[0] * 0.5;
354
355
  const half_v = this.size[2] * 0.5;
@@ -407,13 +408,20 @@ export class HeightMapShape3D extends AbstractShape3D {
407
408
  * (the shared {@link tri3_raycast} convention). A cast from below the terrain
408
409
  * therefore reports a downward normal, not the surface's true upward one.
409
410
  *
410
- * A hit landing exactly ON a sub-cell boundary gets the normal of one of the
411
- * facets meeting there, and which one follows from traversal order: this walks
412
- * the grid along the ray, the narrowphase enumerates it row-major, so on a grid
413
- * line — and especially a grid corner, where four facets meet — the two can
414
- * name different facets. The hit POINT still agrees; a faceted surface simply
415
- * has no single normal at a seam. Measure-zero, and called out because it is
416
- * the only place the two answers part company.
411
+ * A hit landing exactly ON a seam between facets gets the normal of one of the
412
+ * facets meeting there. INSIDE a sub-cell the two paths agree — they split on
413
+ * the same D–B diagonal and break the resulting tie in favour of the same
414
+ * facet — which matters because that diagonal runs through the sub-cell's
415
+ * centre, so a cast down the middle of a cell lands on it routinely rather
416
+ * than exceptionally.
417
+ *
418
+ * BETWEEN sub-cells they can differ, and which facet each names follows from
419
+ * traversal order: this walks the grid along the ray, the narrowphase
420
+ * enumerates it row-major, so on a grid line — and especially a grid corner,
421
+ * where four facets meet — the two can name different facets. The hit POINT
422
+ * still agrees; a faceted surface simply has no single normal at a seam.
423
+ * Measure-zero, and called out because it is the only place the two answers
424
+ * part company.
417
425
  *
418
426
  * `size.y` does NOT bound the query. Sampler values are not clamped to it (see
419
427
  * the class docstring), so clipping the ray to the height range that
@@ -473,10 +481,10 @@ export class HeightMapShape3D extends AbstractShape3D {
473
481
  // Body → heightmap-local footprint coordinates. The basis is orthonormal,
474
482
  // so the direction stays unit and `t` is the same distance in both frames;
475
483
  // the height component is never needed, the triangles carry it.
476
- const o_u = b[0] * o_x + b[1] * o_y + b[2] * o_z;
477
- const o_v = b[3] * o_x + b[4] * o_y + b[5] * o_z;
478
- const d_u = b[0] * d_x + b[1] * d_y + b[2] * d_z;
479
- const d_v = b[3] * d_x + b[4] * d_y + b[5] * d_z;
484
+ const o_u = v3_dot(b[0], b[1], b[2], o_x, o_y, o_z);
485
+ const o_v = v3_dot(b[3], b[4], b[5], o_x, o_y, o_z);
486
+ const d_u = v3_dot(b[0], b[1], b[2], d_x, d_y, d_z);
487
+ const d_v = v3_dot(b[3], b[4], b[5], d_x, d_y, d_z);
480
488
 
481
489
  const half_u = size_x * 0.5;
482
490
  const half_v = size_z * 0.5;
@@ -489,22 +497,22 @@ export class HeightMapShape3D extends AbstractShape3D {
489
497
 
490
498
  if (d_u > RAY_SLAB_EPSILON || d_u < -RAY_SLAB_EPSILON) {
491
499
  const inv = 1 / d_u;
492
- let t0 = (-half_u - o_u) * inv;
493
- let t1 = (half_u - o_u) * inv;
494
- if (t0 > t1) { const s = t0; t0 = t1; t1 = s; }
495
- if (t0 > t_enter) t_enter = t0;
496
- if (t1 < t_exit) t_exit = t1;
500
+ const t0 = (-half_u - o_u) * inv;
501
+ const t1 = (half_u - o_u) * inv;
502
+
503
+ t_enter = Math.max(t_enter, Math.min(t0, t1));
504
+ t_exit = Math.min(t_exit, Math.max(t0, t1));
497
505
  } else if (o_u < -half_u || o_u > half_u) {
498
506
  return false;
499
507
  }
500
508
 
501
509
  if (d_v > RAY_SLAB_EPSILON || d_v < -RAY_SLAB_EPSILON) {
502
510
  const inv = 1 / d_v;
503
- let t0 = (-half_v - o_v) * inv;
504
- let t1 = (half_v - o_v) * inv;
505
- if (t0 > t1) { const s = t0; t0 = t1; t1 = s; }
506
- if (t0 > t_enter) t_enter = t0;
507
- if (t1 < t_exit) t_exit = t1;
511
+ const t0 = (-half_v - o_v) * inv;
512
+ const t1 = (half_v - o_v) * inv;
513
+
514
+ t_enter = Math.max(t_enter, Math.min(t0, t1));
515
+ t_exit = Math.min(t_exit, Math.max(t0, t1));
508
516
  } else if (o_v < -half_v || o_v > half_v) {
509
517
  return false;
510
518
  }
@@ -528,34 +536,33 @@ export class HeightMapShape3D extends AbstractShape3D {
528
536
  const g_u = (o_u + d_u * t_enter + half_u) * per_cell_u;
529
537
  const g_v = (o_v + d_v * t_enter + half_v) * per_cell_v;
530
538
 
531
- // Clamped because the slab clip lands the entry point ON the boundary,
532
- // where rounding can put it a ULP outside the grid.
533
- let i = Math.floor(g_u);
534
- let j = Math.floor(g_v);
535
-
536
- if (i < 0) i = 0; else if (i > seg_u - 1) i = seg_u - 1;
537
- if (j < 0) j = 0; else if (j > seg_v - 1) j = seg_v - 1;
539
+ // Clamped to the grid because the slab clip lands the entry point ON the
540
+ // boundary, where rounding can put it a ULP outside.
541
+ let i = clamp_index(Math.floor(g_u), seg_u);
542
+ let j = clamp_index(Math.floor(g_v), seg_v);
538
543
 
544
+ // `t_next` is the distance at which the ray leaves the starting cell
545
+ // through that axis' far grid line, `t_delta` the distance a whole cell
546
+ // costs thereafter. A zero rate leaves both at Infinity: that axis is
547
+ // never the one the walk steps along.
539
548
  let step_i = 0, t_delta_u = Infinity, t_next_u = Infinity;
540
- if (rate_u > 0) {
541
- step_i = 1;
542
- t_delta_u = 1 / rate_u;
543
- t_next_u = t_enter + (i + 1 - g_u) * t_delta_u;
544
- } else if (rate_u < 0) {
545
- step_i = -1;
546
- t_delta_u = -1 / rate_u;
547
- t_next_u = t_enter + (i - g_u) / rate_u;
549
+ if (rate_u !== 0) {
550
+ // the grid line the starting cell is left through: its far side
551
+ // in the direction of travel
552
+ const exit_line = rate_u > 0 ? i + 1 : i;
553
+
554
+ step_i = rate_u > 0 ? 1 : -1;
555
+ t_delta_u = Math.abs(1 / rate_u);
556
+ t_next_u = t_enter + (exit_line - g_u) / rate_u;
548
557
  }
549
558
 
550
559
  let step_j = 0, t_delta_v = Infinity, t_next_v = Infinity;
551
- if (rate_v > 0) {
552
- step_j = 1;
553
- t_delta_v = 1 / rate_v;
554
- t_next_v = t_enter + (j + 1 - g_v) * t_delta_v;
555
- } else if (rate_v < 0) {
556
- step_j = -1;
557
- t_delta_v = -1 / rate_v;
558
- t_next_v = t_enter + (j - g_v) / rate_v;
560
+ if (rate_v !== 0) {
561
+ const exit_line = rate_v > 0 ? j + 1 : j;
562
+
563
+ step_j = rate_v > 0 ? 1 : -1;
564
+ t_delta_v = Math.abs(1 / rate_v);
565
+ t_next_v = t_enter + (exit_line - g_v) / rate_v;
559
566
  }
560
567
 
561
568
  const inv_seg_u = 1 / seg_u;
@@ -607,25 +614,27 @@ export class HeightMapShape3D extends AbstractShape3D {
607
614
  const Dy = uy * u_lo + vy * v_hi + ny * hD;
608
615
  const Dz = uz * u_lo + vz * v_hi + nz * hD;
609
616
 
610
- // tri3_raycast writes hit[3..5] only for a hit inside the budget it
611
- // was given, so handing the second triangle the first's distance
612
- // leaves the nearer one's normal standing. Both can claim a point on
613
- // the shared D–B diagonal, and this keeps the second where the
614
- // narrowphase's copy of the same test keeps the first — the seam case
615
- // the docstring calls out.
616
- let best = tri3_raycast(
617
+ // Tested in reverse enumeration order, and that is what decides the
618
+ // tie. The two facets share the D–B diagonal — which runs through the
619
+ // sub-cell's centre, so a ray landing on it is the ordinary case, not a
620
+ // corner one — and a ray that lands on it hits both at one distance.
621
+ // `refine_ray_concave` enumerates (A,D,B) first and lets a later
622
+ // triangle win only by a strictly smaller distance, so the facet it
623
+ // names is (A,D,B). tri3_raycast admits `t <= tMax` and writes hit[3..5]
624
+ // only on a hit, so testing (D,C,B) first and handing (A,D,B) its
625
+ // distance as the budget lets the equal hit overwrite the normal — and
626
+ // the two paths name the same facet.
627
+ const t_dcb = tri3_raycast(
617
628
  hit, 3, o_x, o_y, o_z, d_x, d_y, d_z, t_max,
618
- Ax, Ay, Az, Dx, Dy, Dz, Bx, By, Bz
629
+ Dx, Dy, Dz, Cx, Cy, Cz, Bx, By, Bz
619
630
  );
620
631
 
621
- const t_second = tri3_raycast(
622
- hit, 3, o_x, o_y, o_z, d_x, d_y, d_z, best < t_max ? best : t_max,
623
- Dx, Dy, Dz, Cx, Cy, Cz, Bx, By, Bz
632
+ const t_adb = tri3_raycast(
633
+ hit, 3, o_x, o_y, o_z, d_x, d_y, d_z, Math.min(t_dcb, t_max),
634
+ Ax, Ay, Az, Dx, Dy, Dz, Bx, By, Bz
624
635
  );
625
636
 
626
- if (t_second < best) {
627
- best = t_second;
628
- }
637
+ const best = Math.min(t_adb, t_dcb);
629
638
 
630
639
  if (best !== Infinity) {
631
640
  hit[0] = o_x + d_x * best;
@@ -64,11 +64,11 @@ export class FluidObstacleSystem extends System<any> {
64
64
  /**
65
65
  * @param {FluidComponent} fluid
66
66
  */
67
- static "__#396@#refresh_masks"(fluid: FluidComponent): void;
67
+ static "__#403@#refresh_masks"(fluid: FluidComponent): void;
68
68
  /**
69
69
  * @param {FluidComponent} fluid
70
70
  */
71
- static "__#396@#clear_field"(fluid: FluidComponent): void;
71
+ static "__#403@#clear_field"(fluid: FluidComponent): void;
72
72
  /**
73
73
  * Mark every cell of `fluid` whose centre lies within `inflation` of the
74
74
  * posed shape as solid. Iteration is clipped to the shape's world AABB
@@ -80,7 +80,7 @@ export class FluidObstacleSystem extends System<any> {
80
80
  * @param {number} inflation world-units SDF threshold
81
81
  * @param {Float64Array} point length-3 scratch
82
82
  */
83
- static "__#396@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
83
+ static "__#403@#voxelize"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array): void;
84
84
  /**
85
85
  * Write the obstacle's translation velocity onto every face of every cell
86
86
  * it voxelized — the moving-wall boundary condition. Runs AFTER the mask
@@ -100,7 +100,7 @@ export class FluidObstacleSystem extends System<any> {
100
100
  * @param {number} wvy
101
101
  * @param {number} wvz
102
102
  */
103
- static "__#396@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
103
+ static "__#403@#stamp_wall_velocity"(fluid: FluidComponent, posed: PosedShape3D, aabb: Float64Array, inflation: number, point: Float64Array, wvx: number, wvy: number, wvz: number): void;
104
104
  constructor();
105
105
  dependencies: (typeof FluidObstacle)[];
106
106
  components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof RigidBody> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof FluidComponent> | ResourceAccessSpecification<typeof FluidObstacle>)[];