@woosh/meep-engine 3.22.0 → 3.23.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 (267) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
  3. package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
  4. package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
  5. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
  6. package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
  7. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  8. package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
  9. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  10. package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
  11. package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
  12. package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
  13. package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
  14. package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
  15. package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
  16. package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
  17. package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
  18. package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
  20. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
  21. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
  22. package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
  23. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
  24. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
  25. package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
  26. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
  27. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
  29. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
  30. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
  31. package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
  32. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
  33. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
  34. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
  35. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
  36. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
  37. package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
  38. package/src/core/process/ConcurrencyGate.d.ts +103 -0
  39. package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
  40. package/src/core/process/ConcurrencyGate.js +207 -0
  41. package/src/engine/asset/AssetManager.d.ts +10 -0
  42. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  43. package/src/engine/asset/AssetManager.js +10 -0
  44. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
  45. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
  46. package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
  47. package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
  48. package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
  49. package/src/engine/graphics3/pose/query_entity_node_world_pose.js +74 -101
  50. package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
  51. package/src/engine/physics/cloth/PLAN.md +1967 -1581
  52. package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
  53. package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
  54. package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
  55. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
  56. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
  57. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
  58. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
  59. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
  60. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
  61. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
  62. package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
  63. package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
  64. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
  65. package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
  66. package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
  67. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
  68. package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
  69. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
  70. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
  71. package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
  72. package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
  73. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
  74. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
  75. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
  76. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
  77. package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
  78. package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
  79. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
  80. package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
  81. package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
  82. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
  83. package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
  84. package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
  85. package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
  86. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
  87. package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
  88. package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
  89. package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
  90. package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
  91. package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
  92. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
  93. package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
  94. package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
  95. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
  96. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
  97. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
  98. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
  99. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
  100. package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
  101. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
  102. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
  103. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
  104. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
  105. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
  106. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
  107. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
  108. package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
  109. package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
  110. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
  111. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
  112. package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
  113. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -0
  114. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  115. package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -449
  116. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
  117. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
  118. package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
  119. package/src/engine/physics/cloth/playground/README.md +155 -1
  120. package/src/engine/physics/cloth/playground/collide.html +178 -0
  121. package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
  122. package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
  123. package/src/engine/physics/cloth/playground/collide_build.js +315 -0
  124. package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
  125. package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
  126. package/src/engine/physics/cloth/playground/collide_main.js +720 -0
  127. package/src/engine/physics/cloth/playground/garment.html +182 -0
  128. package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
  129. package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
  130. package/src/engine/physics/cloth/playground/garment_build.js +359 -0
  131. package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
  132. package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
  133. package/src/engine/physics/cloth/playground/garment_main.js +633 -0
  134. package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
  135. package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
  136. package/src/engine/physics/cloth/solver/ClothState.js +302 -8
  137. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
  138. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
  139. package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
  140. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
  141. package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
  142. package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
  143. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
  144. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  145. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
  146. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
  147. package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
  148. package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
  149. package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
  150. package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
  151. package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
  152. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
  153. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
  154. package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
  155. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
  156. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
  157. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
  158. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
  159. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
  160. package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
  161. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  162. package/src/shade/playground/vgeo_viewer/README.md +18 -0
  163. package/src/shade/playground/vgeo_viewer/main.js +87 -50
  164. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  165. package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
  166. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
  167. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  168. package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
  169. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
  170. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
  171. package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
  172. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
  173. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
  174. package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
  175. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
  176. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  177. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
  178. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
  179. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
  180. package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
  181. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
  182. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  183. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
  184. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
  185. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
  186. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
  187. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
  188. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
  189. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
  190. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
  191. package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
  192. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
  193. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  194. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
  195. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
  196. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
  197. package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
  198. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
  199. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
  201. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
  202. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
  204. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
  205. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
  206. package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
  207. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
  208. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
  209. package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
  210. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
  211. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
  212. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
  213. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
  214. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
  215. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
  216. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  217. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  218. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
  219. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
  220. package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
  221. package/src/shade/renderer/texture/virtual/README.md +6 -4
  222. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  223. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
  224. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
  225. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
  226. package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
  227. package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
  228. package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
  229. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
  230. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
  231. package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
  232. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
  233. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
  234. package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
  235. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
  236. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
  237. package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
  238. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
  239. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
  240. package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
  241. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
  242. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
  243. package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
  244. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
  245. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
  246. package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
  247. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
  248. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
  249. package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
  250. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
  251. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
  252. package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
  253. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
  254. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
  255. package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
  256. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
  257. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
  258. package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
  259. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
  260. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
  261. package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
  262. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
  263. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
  264. package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
  265. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
  266. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
  267. package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
@@ -0,0 +1,173 @@
1
+ import { BoxShape3D } from "../../../../core/geom/3d/shape/BoxShape3D.js";
2
+ import { CapsuleShape3D } from "../../../../core/geom/3d/shape/CapsuleShape3D.js";
3
+ import { CylinderShape3D } from "../../../../core/geom/3d/shape/CylinderShape3D.js";
4
+ import { PlaneShape3D } from "../../../../core/geom/3d/shape/PlaneShape3D.js";
5
+ import { SphereShape3D } from "../../../../core/geom/3d/shape/SphereShape3D.js";
6
+ import { ClothColliderKind } from "./ClothColliderKind.js";
7
+ import {
8
+ CCR_FEATURE,
9
+ CCR_KIND,
10
+ CCR_PARAM_0,
11
+ CCR_PARAM_1,
12
+ CCR_PARAM_2,
13
+ CCR_PARAM_3
14
+ } from "./ClothColliderRecord.js";
15
+
16
+ /**
17
+ * # `AbstractShape3D` → a packed record's geometry
18
+ *
19
+ * The one place a cloth collider is a shape object rather than a row of floats.
20
+ * It runs when a `ClothCollider` is linked or its shape changes, never per step
21
+ * and never per particle.
22
+ *
23
+ * `instanceof` rather than the prototype markers the physics narrowphase uses,
24
+ * because this needs to distinguish *five* kinds rather than short-circuit one,
25
+ * and because a marker per kind would be five new fields on `core` shapes for
26
+ * one consumer's benefit. The ordering matters in one place and is commented
27
+ * where it does.
28
+ *
29
+ * @author Alex Goldring
30
+ * @copyright Company Named Limited (c) 2026
31
+ */
32
+
33
+ /**
34
+ * Write a shape's kind, parameters and feature size into a record.
35
+ *
36
+ * @param {Float32Array|Float64Array} table
37
+ * @param {number} record record index, not a slot offset
38
+ * @param {AbstractShape3D} shape in its canonical local frame
39
+ * @param {number} stride
40
+ * @returns {boolean} `false` if the shape is not one cloth can collide against,
41
+ * in which case nothing was written
42
+ */
43
+ export function cloth_collider_pack(table, record, shape, stride) {
44
+ const r = record * stride;
45
+
46
+ if (shape instanceof SphereShape3D) {
47
+ // Covers UnitSphereShape3D, which is a SphereShape3D of radius 1.
48
+ const radius = shape.radius;
49
+
50
+ table[r + CCR_KIND] = ClothColliderKind.Sphere;
51
+ table[r + CCR_PARAM_0] = radius;
52
+ table[r + CCR_PARAM_1] = 0;
53
+ table[r + CCR_PARAM_2] = 0;
54
+ table[r + CCR_PARAM_3] = 0;
55
+ table[r + CCR_FEATURE] = radius;
56
+
57
+ return true;
58
+ }
59
+
60
+ if (shape instanceof CapsuleShape3D) {
61
+ const radius = shape.radius;
62
+
63
+ table[r + CCR_KIND] = ClothColliderKind.Capsule;
64
+ table[r + CCR_PARAM_0] = radius;
65
+ table[r + CCR_PARAM_1] = shape.height;
66
+ table[r + CCR_PARAM_2] = 0;
67
+ table[r + CCR_PARAM_3] = 0;
68
+
69
+ // A capsule's tightest curvature is its cap, which is its own radius.
70
+ table[r + CCR_FEATURE] = radius;
71
+
72
+ return true;
73
+ }
74
+
75
+ if (shape instanceof BoxShape3D) {
76
+ // Covers UnitCubeShape3D, which is a BoxShape3D pinned to 0.5.
77
+ const h = shape.half_extents;
78
+
79
+ table[r + CCR_KIND] = ClothColliderKind.Box;
80
+ table[r + CCR_PARAM_0] = h.x;
81
+ table[r + CCR_PARAM_1] = h.y;
82
+ table[r + CCR_PARAM_2] = h.z;
83
+ table[r + CCR_PARAM_3] = 0;
84
+
85
+ // A box has no curvature; its edges are creases, and the distance over
86
+ // which "the nearest face's normal" describes the surface is how far
87
+ // the nearest face extends — its smallest half-extent, conservatively.
88
+ table[r + CCR_FEATURE] = Math.min(h.x, Math.min(h.y, h.z));
89
+
90
+ return true;
91
+ }
92
+
93
+ if (shape instanceof CylinderShape3D) {
94
+ const radius = shape.radius;
95
+
96
+ table[r + CCR_KIND] = ClothColliderKind.Cylinder;
97
+ table[r + CCR_PARAM_0] = radius;
98
+ table[r + CCR_PARAM_1] = shape.height;
99
+ table[r + CCR_PARAM_2] = 0;
100
+ table[r + CCR_PARAM_3] = 0;
101
+ table[r + CCR_FEATURE] = Math.min(radius, shape.height * 0.5);
102
+
103
+ return true;
104
+ }
105
+
106
+ if (shape instanceof PlaneShape3D) {
107
+ table[r + CCR_KIND] = ClothColliderKind.Plane;
108
+ table[r + CCR_PARAM_0] = shape.normal_x;
109
+ table[r + CCR_PARAM_1] = shape.normal_y;
110
+ table[r + CCR_PARAM_2] = shape.normal_z;
111
+ table[r + CCR_PARAM_3] = shape.offset;
112
+
113
+ // A plane is flat everywhere, so its normal describes it at any
114
+ // distance and it never narrows a trust region.
115
+ table[r + CCR_FEATURE] = Infinity;
116
+
117
+ return true;
118
+ }
119
+
120
+ return false;
121
+ }
122
+
123
+ /**
124
+ * The AABB of a packed shape in its own local frame, ignoring pose.
125
+ *
126
+ * Written here rather than taken from `AbstractShape3D#compute_bounding_box`
127
+ * because a plane's box is `±Infinity` on its unbounded axes and the caller
128
+ * transforms this one — `0 · Infinity` is `NaN`, so an unbounded local box
129
+ * cannot go through a pose. {@link cloth_collider_local_bounds} therefore
130
+ * refuses a plane and the index bounds one directly from its world normal.
131
+ *
132
+ * @param {Float64Array|number[]} out `[x0, y0, z0, x1, y1, z1]`
133
+ * @param {Float32Array|Float64Array} table
134
+ * @param {number} record
135
+ * @param {number} stride
136
+ * @returns {boolean} `false` for an unbounded kind, in which case `out` is untouched
137
+ */
138
+ export function cloth_collider_local_bounds(out, table, record, stride) {
139
+ const r = record * stride;
140
+
141
+ const kind = table[r + CCR_KIND];
142
+
143
+ let hx;
144
+ let hy;
145
+ let hz;
146
+
147
+ if (kind === ClothColliderKind.Sphere) {
148
+ hx = hy = hz = table[r + CCR_PARAM_0];
149
+ } else if (kind === ClothColliderKind.Capsule) {
150
+ const radius = table[r + CCR_PARAM_0];
151
+
152
+ hx = hz = radius;
153
+ hy = radius + table[r + CCR_PARAM_1] * 0.5;
154
+ } else if (kind === ClothColliderKind.Box) {
155
+ hx = table[r + CCR_PARAM_0];
156
+ hy = table[r + CCR_PARAM_1];
157
+ hz = table[r + CCR_PARAM_2];
158
+ } else if (kind === ClothColliderKind.Cylinder) {
159
+ hx = hz = table[r + CCR_PARAM_0];
160
+ hy = table[r + CCR_PARAM_1] * 0.5;
161
+ } else {
162
+ return false;
163
+ }
164
+
165
+ out[0] = -hx;
166
+ out[1] = -hy;
167
+ out[2] = -hz;
168
+ out[3] = hx;
169
+ out[4] = hy;
170
+ out[5] = hz;
171
+
172
+ return true;
173
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * # Evaluating a packed collider
3
+ *
4
+ * Two functions, and between them they are the whole of §8.2. One writes a
5
+ * collider's pose interpolated to a substep; the other evaluates its signed
6
+ * distance and gradient at a point, in the frame the table is expressed in.
7
+ *
8
+ * The evaluation is: bring the point into the collider's local frame with the
9
+ * inverse of the interpolated pose, evaluate the closed-form field there, and
10
+ * rotate the gradient back. That is three steps and no matrix — a rigid pose
11
+ * inverts by conjugating its quaternion and subtracting its translation, which
12
+ * costs less than storing an inverse and is exact rather than cached.
13
+ *
14
+ * The fields themselves live in `core/geom/3d/shape/sdf/` as free functions
15
+ * over scalars, so this dispatch and {@link SphereShape3D} and the rest are
16
+ * calling one implementation (§14.1). Before M2 those shapes fell back to
17
+ * `compute_signed_distance_gradient_by_sampling` — four field evaluations and a
18
+ * normalise, for shapes whose gradients are two lines of algebra.
19
+ *
20
+ * @author Alex Goldring
21
+ * @copyright Company Named Limited (c) 2026
22
+ */
23
+ /**
24
+ * Write every collider's pose interpolated to fraction `t` of the step into its
25
+ * own record. `t = 0` is the previous step's pose and `t = 1` is this one's.
26
+ *
27
+ * **This is the whole of "swept collision", and it is swept in translation and
28
+ * rotation but not in the *contact set*.** Which particles are in contact is
29
+ * decided once per step; where those colliders are is decided once per substep.
30
+ * The limit §7 P3 states — a collider spinning fast enough that a point on its
31
+ * surface travels more than its own radius within one substep can still be
32
+ * missed — is a limit on the second of those, and more substeps is the answer
33
+ * to it.
34
+ *
35
+ * The rotation is an `nlerp` rather than a `slerp`: it is not constant angular
36
+ * velocity, and over the fraction of a fixed step it is indistinguishable from
37
+ * one — the two differ by under a thousandth of a degree at the half-radian per
38
+ * step `CLOTH_ANCHOR_ROTATION_LIMIT` already treats as a spin.
39
+ *
40
+ * @param {Float32Array|Float64Array} table
41
+ * @param {number} count records in `table`
42
+ * @param {number} t `[0, 1]`
43
+ * @returns {void}
44
+ */
45
+ export function cloth_collider_pose_at(table: Float32Array | Float64Array, count: number, t: number): void;
46
+ /**
47
+ * Signed distance from a point to one packed collider's surface, with the unit
48
+ * outward gradient written into `gradient` at `gradient_offset`.
49
+ *
50
+ * The point and the gradient are both in the frame `table` is expressed in.
51
+ *
52
+ * @param {Float32Array|Float64Array|number[]} gradient
53
+ * @param {number} gradient_offset
54
+ * @param {Float32Array|Float64Array} table
55
+ * @param {number} record record index, not a slot offset
56
+ * @param {number} x
57
+ * @param {number} y
58
+ * @param {number} z
59
+ * @returns {number} the signed distance
60
+ */
61
+ export function cloth_collider_signed_distance(gradient: Float32Array | Float64Array | number[], gradient_offset: number, table: Float32Array | Float64Array, record: number, x: number, y: number, z: number): number;
62
+ /**
63
+ * Bring a point expressed in a collider's own local frame out into the frame
64
+ * the table is expressed in, using the interpolated pose. This is the inverse
65
+ * of the localisation above, and it is what carries a friction anchor with a
66
+ * moving collider (§8.3): the anchor is stored where the collider will always
67
+ * agree it is, and read back wherever the collider has moved to.
68
+ *
69
+ * @param {Float32Array|Float64Array|number[]} out
70
+ * @param {number} out_offset
71
+ * @param {Float32Array|Float64Array} table
72
+ * @param {number} record
73
+ * @param {number} x local
74
+ * @param {number} y local
75
+ * @param {number} z local
76
+ * @returns {void}
77
+ */
78
+ export function cloth_collider_from_local(out: Float32Array | Float64Array | number[], out_offset: number, table: Float32Array | Float64Array, record: number, x: number, y: number, z: number): void;
79
+ /**
80
+ * Bring a point out of the table's frame into a collider's own local frame,
81
+ * using the interpolated pose. The anchoring half of
82
+ * {@link cloth_collider_from_local}.
83
+ *
84
+ * @param {Float32Array|Float64Array|number[]} out
85
+ * @param {number} out_offset
86
+ * @param {Float32Array|Float64Array} table
87
+ * @param {number} record
88
+ * @param {number} x
89
+ * @param {number} y
90
+ * @param {number} z
91
+ * @returns {void}
92
+ */
93
+ export function cloth_collider_to_local(out: Float32Array | Float64Array | number[], out_offset: number, table: Float32Array | Float64Array, record: number, x: number, y: number, z: number): void;
94
+ //# sourceMappingURL=cloth_collider_sdf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloth_collider_sdf.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/collider/cloth_collider_sdf.js"],"names":[],"mappings":"AAsCA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,8CALW,YAAY,GAAC,YAAY,SACzB,MAAM,KACN,MAAM,GACJ,IAAI,CAiDhB;AAED;;;;;;;;;;;;;;GAcG;AACH,yDATW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,mBAClC,MAAM,SACN,YAAY,GAAC,YAAY,UACzB,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,MAAM,CA4DlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,+CATW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,cAClC,MAAM,SACN,YAAY,GAAC,YAAY,UACzB,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,IAAI,CAchB;AAED;;;;;;;;;;;;;GAaG;AACH,6CATW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,cAClC,MAAM,SACN,YAAY,GAAC,YAAY,UACzB,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,IAAI,CAahB"}
@@ -0,0 +1,275 @@
1
+ import { sdf3_box_gradient } from "../../../../core/geom/3d/shape/sdf/sdf3_box.js";
2
+ import { sdf3_capsule_gradient } from "../../../../core/geom/3d/shape/sdf/sdf3_capsule.js";
3
+ import { sdf3_cylinder_gradient } from "../../../../core/geom/3d/shape/sdf/sdf3_cylinder.js";
4
+ import { sdf3_plane_gradient } from "../../../../core/geom/3d/shape/sdf/sdf3_plane.js";
5
+ import { sdf3_sphere_gradient } from "../../../../core/geom/3d/shape/sdf/sdf3_sphere.js";
6
+ import { v3_quaternion_apply } from "../../../../core/geom/vec3/v3_quaternion_apply.js";
7
+ import { v3_quaternion_apply_inverse } from "../../../../core/geom/vec3/v3_quaternion_apply_inverse.js";
8
+ import {
9
+ CCR_INTERP_QW,
10
+ CCR_INTERP_QX,
11
+ CCR_INTERP_QY,
12
+ CCR_INTERP_QZ,
13
+ CCR_INTERP_TX,
14
+ CCR_INTERP_TY,
15
+ CCR_INTERP_TZ,
16
+ CCR_KIND,
17
+ CCR_PARAM_0,
18
+ CCR_PARAM_1,
19
+ CCR_PARAM_2,
20
+ CCR_PARAM_3,
21
+ CCR_PREV_QW,
22
+ CCR_PREV_QX,
23
+ CCR_PREV_QY,
24
+ CCR_PREV_QZ,
25
+ CCR_PREV_TX,
26
+ CCR_PREV_TY,
27
+ CCR_PREV_TZ,
28
+ CCR_QW,
29
+ CCR_QX,
30
+ CCR_QY,
31
+ CCR_QZ,
32
+ CCR_STRIDE,
33
+ CCR_TX,
34
+ CCR_TY,
35
+ CCR_TZ
36
+ } from "./ClothColliderRecord.js";
37
+ import { ClothColliderKind } from "./ClothColliderKind.js";
38
+
39
+ /**
40
+ * # Evaluating a packed collider
41
+ *
42
+ * Two functions, and between them they are the whole of §8.2. One writes a
43
+ * collider's pose interpolated to a substep; the other evaluates its signed
44
+ * distance and gradient at a point, in the frame the table is expressed in.
45
+ *
46
+ * The evaluation is: bring the point into the collider's local frame with the
47
+ * inverse of the interpolated pose, evaluate the closed-form field there, and
48
+ * rotate the gradient back. That is three steps and no matrix — a rigid pose
49
+ * inverts by conjugating its quaternion and subtracting its translation, which
50
+ * costs less than storing an inverse and is exact rather than cached.
51
+ *
52
+ * The fields themselves live in `core/geom/3d/shape/sdf/` as free functions
53
+ * over scalars, so this dispatch and {@link SphereShape3D} and the rest are
54
+ * calling one implementation (§14.1). Before M2 those shapes fell back to
55
+ * `compute_signed_distance_gradient_by_sampling` — four field evaluations and a
56
+ * normalise, for shapes whose gradients are two lines of algebra.
57
+ *
58
+ * @author Alex Goldring
59
+ * @copyright Company Named Limited (c) 2026
60
+ */
61
+
62
+ /**
63
+ * Write every collider's pose interpolated to fraction `t` of the step into its
64
+ * own record. `t = 0` is the previous step's pose and `t = 1` is this one's.
65
+ *
66
+ * **This is the whole of "swept collision", and it is swept in translation and
67
+ * rotation but not in the *contact set*.** Which particles are in contact is
68
+ * decided once per step; where those colliders are is decided once per substep.
69
+ * The limit §7 P3 states — a collider spinning fast enough that a point on its
70
+ * surface travels more than its own radius within one substep can still be
71
+ * missed — is a limit on the second of those, and more substeps is the answer
72
+ * to it.
73
+ *
74
+ * The rotation is an `nlerp` rather than a `slerp`: it is not constant angular
75
+ * velocity, and over the fraction of a fixed step it is indistinguishable from
76
+ * one — the two differ by under a thousandth of a degree at the half-radian per
77
+ * step `CLOTH_ANCHOR_ROTATION_LIMIT` already treats as a spin.
78
+ *
79
+ * @param {Float32Array|Float64Array} table
80
+ * @param {number} count records in `table`
81
+ * @param {number} t `[0, 1]`
82
+ * @returns {void}
83
+ */
84
+ export function cloth_collider_pose_at(table, count, t) {
85
+ const s = 1 - t;
86
+
87
+ for (let i = 0; i < count; i++) {
88
+ const r = i * CCR_STRIDE;
89
+
90
+ table[r + CCR_INTERP_TX] = s * table[r + CCR_PREV_TX] + t * table[r + CCR_TX];
91
+ table[r + CCR_INTERP_TY] = s * table[r + CCR_PREV_TY] + t * table[r + CCR_TY];
92
+ table[r + CCR_INTERP_TZ] = s * table[r + CCR_PREV_TZ] + t * table[r + CCR_TZ];
93
+
94
+ const ax = table[r + CCR_PREV_QX];
95
+ const ay = table[r + CCR_PREV_QY];
96
+ const az = table[r + CCR_PREV_QZ];
97
+ const aw = table[r + CCR_PREV_QW];
98
+
99
+ let bx = table[r + CCR_QX];
100
+ let by = table[r + CCR_QY];
101
+ let bz = table[r + CCR_QZ];
102
+ let bw = table[r + CCR_QW];
103
+
104
+ // `q` and `−q` are one rotation, so the pair has to be brought onto the
105
+ // same hemisphere or the interpolation takes the long way round — which
106
+ // for a collider is a bone that spins through the character.
107
+ if (ax * bx + ay * by + az * bz + aw * bw < 0) {
108
+ bx = -bx;
109
+ by = -by;
110
+ bz = -bz;
111
+ bw = -bw;
112
+ }
113
+
114
+ const qx = s * ax + t * bx;
115
+ const qy = s * ay + t * by;
116
+ const qz = s * az + t * bz;
117
+ const qw = s * aw + t * bw;
118
+
119
+ const length = Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
120
+
121
+ // Two opposed quaternions cancel exactly, which the hemisphere fix
122
+ // above makes impossible; the guard is for a record whose poses were
123
+ // never written rather than for a rotation.
124
+ const inverse = length > 0 ? 1 / length : 0;
125
+
126
+ table[r + CCR_INTERP_QX] = qx * inverse;
127
+ table[r + CCR_INTERP_QY] = qy * inverse;
128
+ table[r + CCR_INTERP_QZ] = qz * inverse;
129
+ table[r + CCR_INTERP_QW] = length > 0 ? qw * inverse : 1;
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Signed distance from a point to one packed collider's surface, with the unit
135
+ * outward gradient written into `gradient` at `gradient_offset`.
136
+ *
137
+ * The point and the gradient are both in the frame `table` is expressed in.
138
+ *
139
+ * @param {Float32Array|Float64Array|number[]} gradient
140
+ * @param {number} gradient_offset
141
+ * @param {Float32Array|Float64Array} table
142
+ * @param {number} record record index, not a slot offset
143
+ * @param {number} x
144
+ * @param {number} y
145
+ * @param {number} z
146
+ * @returns {number} the signed distance
147
+ */
148
+ export function cloth_collider_signed_distance(gradient, gradient_offset, table, record, x, y, z) {
149
+ const r = record * CCR_STRIDE;
150
+
151
+ const qx = table[r + CCR_INTERP_QX];
152
+ const qy = table[r + CCR_INTERP_QY];
153
+ const qz = table[r + CCR_INTERP_QZ];
154
+ const qw = table[r + CCR_INTERP_QW];
155
+
156
+ v3_quaternion_apply_inverse(
157
+ LOCAL_POINT, 0,
158
+ x - table[r + CCR_INTERP_TX],
159
+ y - table[r + CCR_INTERP_TY],
160
+ z - table[r + CCR_INTERP_TZ],
161
+ qx, qy, qz, qw
162
+ );
163
+
164
+ const lx = LOCAL_POINT[0];
165
+ const ly = LOCAL_POINT[1];
166
+ const lz = LOCAL_POINT[2];
167
+
168
+ const kind = table[r + CCR_KIND];
169
+
170
+ let distance;
171
+
172
+ if (kind === ClothColliderKind.Sphere) {
173
+ distance = sdf3_sphere_gradient(LOCAL_GRADIENT, 0, lx, ly, lz, table[r + CCR_PARAM_0]);
174
+ } else if (kind === ClothColliderKind.Capsule) {
175
+ distance = sdf3_capsule_gradient(
176
+ LOCAL_GRADIENT, 0, lx, ly, lz,
177
+ table[r + CCR_PARAM_0], table[r + CCR_PARAM_1]
178
+ );
179
+ } else if (kind === ClothColliderKind.Box) {
180
+ distance = sdf3_box_gradient(
181
+ LOCAL_GRADIENT, 0, lx, ly, lz,
182
+ table[r + CCR_PARAM_0], table[r + CCR_PARAM_1], table[r + CCR_PARAM_2]
183
+ );
184
+ } else if (kind === ClothColliderKind.Cylinder) {
185
+ distance = sdf3_cylinder_gradient(
186
+ LOCAL_GRADIENT, 0, lx, ly, lz,
187
+ table[r + CCR_PARAM_0], table[r + CCR_PARAM_1]
188
+ );
189
+ } else {
190
+ distance = sdf3_plane_gradient(
191
+ LOCAL_GRADIENT, 0, lx, ly, lz,
192
+ table[r + CCR_PARAM_0], table[r + CCR_PARAM_1], table[r + CCR_PARAM_2],
193
+ table[r + CCR_PARAM_3]
194
+ );
195
+ }
196
+
197
+ // The gradient is a direction, so it takes the rotation and not the
198
+ // translation.
199
+ v3_quaternion_apply(
200
+ gradient, gradient_offset,
201
+ LOCAL_GRADIENT[0], LOCAL_GRADIENT[1], LOCAL_GRADIENT[2],
202
+ qx, qy, qz, qw
203
+ );
204
+
205
+ return distance;
206
+ }
207
+
208
+ /**
209
+ * Bring a point expressed in a collider's own local frame out into the frame
210
+ * the table is expressed in, using the interpolated pose. This is the inverse
211
+ * of the localisation above, and it is what carries a friction anchor with a
212
+ * moving collider (§8.3): the anchor is stored where the collider will always
213
+ * agree it is, and read back wherever the collider has moved to.
214
+ *
215
+ * @param {Float32Array|Float64Array|number[]} out
216
+ * @param {number} out_offset
217
+ * @param {Float32Array|Float64Array} table
218
+ * @param {number} record
219
+ * @param {number} x local
220
+ * @param {number} y local
221
+ * @param {number} z local
222
+ * @returns {void}
223
+ */
224
+ export function cloth_collider_from_local(out, out_offset, table, record, x, y, z) {
225
+ const r = record * CCR_STRIDE;
226
+
227
+ v3_quaternion_apply(
228
+ out, out_offset, x, y, z,
229
+ table[r + CCR_INTERP_QX], table[r + CCR_INTERP_QY],
230
+ table[r + CCR_INTERP_QZ], table[r + CCR_INTERP_QW]
231
+ );
232
+
233
+ out[out_offset] += table[r + CCR_INTERP_TX];
234
+ out[out_offset + 1] += table[r + CCR_INTERP_TY];
235
+ out[out_offset + 2] += table[r + CCR_INTERP_TZ];
236
+ }
237
+
238
+ /**
239
+ * Bring a point out of the table's frame into a collider's own local frame,
240
+ * using the interpolated pose. The anchoring half of
241
+ * {@link cloth_collider_from_local}.
242
+ *
243
+ * @param {Float32Array|Float64Array|number[]} out
244
+ * @param {number} out_offset
245
+ * @param {Float32Array|Float64Array} table
246
+ * @param {number} record
247
+ * @param {number} x
248
+ * @param {number} y
249
+ * @param {number} z
250
+ * @returns {void}
251
+ */
252
+ export function cloth_collider_to_local(out, out_offset, table, record, x, y, z) {
253
+ const r = record * CCR_STRIDE;
254
+
255
+ v3_quaternion_apply_inverse(
256
+ out, out_offset,
257
+ x - table[r + CCR_INTERP_TX],
258
+ y - table[r + CCR_INTERP_TY],
259
+ z - table[r + CCR_INTERP_TZ],
260
+ table[r + CCR_INTERP_QX], table[r + CCR_INTERP_QY],
261
+ table[r + CCR_INTERP_QZ], table[r + CCR_INTERP_QW]
262
+ );
263
+ }
264
+
265
+ /**
266
+ * @type {Float64Array}
267
+ * @private
268
+ */
269
+ const LOCAL_GRADIENT = new Float64Array(3);
270
+
271
+ /**
272
+ * @type {Float64Array}
273
+ * @private
274
+ */
275
+ const LOCAL_POINT = new Float64Array(3);
@@ -0,0 +1,126 @@
1
+ /**
2
+ * # The marker that opts a collider into cloth
3
+ *
4
+ * Put this beside an existing `(Collider, Transform64)` and cloth collides
5
+ * against it. That is the whole of the component's job, and it is the third
6
+ * instance of a pattern the engine already has twice: `AcousticBody` opts a
7
+ * collider into the acoustic simulation and carries an `AcousticMaterial`,
8
+ * `FluidObstacle` opts a collider into the fluid simulation and carries an
9
+ * inflation radius. This should read as a sibling of those two rather than as a
10
+ * new invention.
11
+ *
12
+ * Everything not here is read from components the entity already has: geometry
13
+ * and friction from `Collider`, pose from `Transform64`.
14
+ *
15
+ * ## No `RigidBody` required
16
+ *
17
+ * A deliberate divergence from `FluidObstacle`, which requires one because it
18
+ * needs a wall velocity. Cloth's colliders are overwhelmingly character bones —
19
+ * ordinary entities in a `TransformAttachment` hierarchy — and making each of
20
+ * them a physics body to be seen by cloth would tax the common case. Collider
21
+ * velocity is derived from the pose delta between fixed steps, which the index
22
+ * caches anyway for swept collision (§8.2). A world prop that *does* carry a
23
+ * `RigidBody` adds a `ClothCollider` the same way and lands in the same index;
24
+ * the two cases are not distinguished.
25
+ *
26
+ * ## Layer and mask, which §3.5 did not have
27
+ *
28
+ * §3.5 gives this component three fields and says layer filtering comes "from
29
+ * the `Cloth` side". It cannot: `Cloth#mask` is a mask *of collider layers*,
30
+ * and with no `RigidBody` required there is nowhere else for a collider's layer
31
+ * to live. So the pair is here, with `RigidBody`'s own semantics — a cloth and
32
+ * a collider interact when each is in the other's mask — which is what
33
+ * `Cloth.js` already says it means by "`RigidBody` semantics".
34
+ *
35
+ * @author Alex Goldring
36
+ * @copyright Company Named Limited (c) 2026
37
+ */
38
+ export class ClothCollider {
39
+ /**
40
+ * @param {object} [spec]
41
+ * @param {number} [spec.inflation]
42
+ * @param {number} [spec.friction_scale]
43
+ * @param {number} [spec.layer]
44
+ * @param {number} [spec.mask]
45
+ * @param {number} [spec.flags]
46
+ * @returns {ClothCollider}
47
+ */
48
+ static from(spec?: {
49
+ inflation?: number;
50
+ friction_scale?: number;
51
+ layer?: number;
52
+ mask?: number;
53
+ flags?: number;
54
+ }): ClothCollider;
55
+ /**
56
+ * Extra thickness in metres, on top of `ClothDynamics#thickness`.
57
+ *
58
+ * The contact row holds cloth at `thickness + inflation` from the surface,
59
+ * so this is how a garment is kept off a body it would otherwise graze —
60
+ * the same idea as `FluidObstacle#inflation`, and useful for the same
61
+ * reason: a collider that approximates a limb loosely wants the cloth held
62
+ * a little further out than the approximation.
63
+ * @type {number}
64
+ */
65
+ inflation: number;
66
+ /**
67
+ * Multiplies the entity's `Collider#friction` before it is combined with
68
+ * the cloth's own. `0` makes the surface frictionless to cloth without
69
+ * making it frictionless to rigid bodies, which is the case this exists
70
+ * for: a character's collision capsules are tuned for footing, and a cape
71
+ * that grips them the same way reads as glued.
72
+ * @type {number}
73
+ */
74
+ friction_scale: number;
75
+ /**
76
+ * Collision layer this collider belongs to, `RigidBody` semantics.
77
+ * @type {number}
78
+ */
79
+ layer: number;
80
+ /**
81
+ * Which `Cloth` layers this collider acts on.
82
+ * @type {number}
83
+ */
84
+ mask: number;
85
+ /**
86
+ * @see ClothColliderFlags
87
+ * @type {number}
88
+ */
89
+ flags: number;
90
+ /**
91
+ * @param {number|ClothColliderFlags} flag
92
+ * @returns {boolean}
93
+ */
94
+ getFlag(flag: number | ClothColliderFlags): boolean;
95
+ /**
96
+ * @param {ClothCollider} other
97
+ * @returns {boolean}
98
+ */
99
+ equals(other: ClothCollider): boolean;
100
+ /**
101
+ * @returns {number}
102
+ */
103
+ hash(): number;
104
+ toJSON(): {
105
+ inflation: number;
106
+ friction_scale: number;
107
+ layer: number;
108
+ mask: number;
109
+ flags: number;
110
+ };
111
+ /**
112
+ * @param {object} json
113
+ */
114
+ fromJSON({ inflation, friction_scale, layer, mask, flags }: object): void;
115
+ toString(): string;
116
+ /**
117
+ * @readonly
118
+ * @type {boolean}
119
+ */
120
+ readonly isClothCollider: boolean;
121
+ }
122
+ export namespace ClothCollider {
123
+ let typeName: string;
124
+ }
125
+ import { ClothColliderFlags } from "./ClothColliderFlags.js";
126
+ //# sourceMappingURL=ClothCollider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothCollider.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothCollider.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IA0CI;;;;;;;;OAQG;IACH;QAPyB,SAAS,GAAvB,MAAM;QACQ,cAAc,GAA5B,MAAM;QACQ,KAAK,GAAnB,MAAM;QACQ,IAAI,GAAlB,MAAM;QACQ,KAAK,GAAnB,MAAM;QACJ,aAAa,CA0BzB;IAzED;;;;;;;;;OASG;IACH,WAFU,MAAM,CAEF;IAEd;;;;;;;OAOG;IACH,gBAFU,MAAM,CAEG;IAEnB;;;OAGG;IACH,OAFU,MAAM,CAEN;IAEV;;;OAGG;IACH,MAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,OAFU,MAAM,CAEgB;IAqChC;;;OAGG;IACH,cAHW,MAAM,GAAC,kBAAkB,GACvB,OAAO,CAInB;IAED;;;OAGG;IACH,cAHW,aAAa,GACX,OAAO,CAgBnB;IAED;;OAEG;IACH,QAFa,MAAM,CAUlB;IAED;;;;;;MAQC;IAED;;OAEG;IACH,4DAFW,MAAM,QAchB;IAED,mBAEC;IAGL;;;OAGG;IACH,0BAFU,OAAO,CAEsB;CANtC;;;;mCA3LkC,yBAAyB"}