@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,199 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { combine_hash } from "../../../../core/collection/array/combine_hash.js";
3
+ import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
4
+ import { ClothColliderFlags } from "./ClothColliderFlags.js";
5
+
6
+ /**
7
+ * # The marker that opts a collider into cloth
8
+ *
9
+ * Put this beside an existing `(Collider, Transform64)` and cloth collides
10
+ * against it. That is the whole of the component's job, and it is the third
11
+ * instance of a pattern the engine already has twice: `AcousticBody` opts a
12
+ * collider into the acoustic simulation and carries an `AcousticMaterial`,
13
+ * `FluidObstacle` opts a collider into the fluid simulation and carries an
14
+ * inflation radius. This should read as a sibling of those two rather than as a
15
+ * new invention.
16
+ *
17
+ * Everything not here is read from components the entity already has: geometry
18
+ * and friction from `Collider`, pose from `Transform64`.
19
+ *
20
+ * ## No `RigidBody` required
21
+ *
22
+ * A deliberate divergence from `FluidObstacle`, which requires one because it
23
+ * needs a wall velocity. Cloth's colliders are overwhelmingly character bones —
24
+ * ordinary entities in a `TransformAttachment` hierarchy — and making each of
25
+ * them a physics body to be seen by cloth would tax the common case. Collider
26
+ * velocity is derived from the pose delta between fixed steps, which the index
27
+ * caches anyway for swept collision (§8.2). A world prop that *does* carry a
28
+ * `RigidBody` adds a `ClothCollider` the same way and lands in the same index;
29
+ * the two cases are not distinguished.
30
+ *
31
+ * ## Layer and mask, which §3.5 did not have
32
+ *
33
+ * §3.5 gives this component three fields and says layer filtering comes "from
34
+ * the `Cloth` side". It cannot: `Cloth#mask` is a mask *of collider layers*,
35
+ * and with no `RigidBody` required there is nowhere else for a collider's layer
36
+ * to live. So the pair is here, with `RigidBody`'s own semantics — a cloth and
37
+ * a collider interact when each is in the other's mask — which is what
38
+ * `Cloth.js` already says it means by "`RigidBody` semantics".
39
+ *
40
+ * @author Alex Goldring
41
+ * @copyright Company Named Limited (c) 2026
42
+ */
43
+ export class ClothCollider {
44
+
45
+ /**
46
+ * Extra thickness in metres, on top of `ClothDynamics#thickness`.
47
+ *
48
+ * The contact row holds cloth at `thickness + inflation` from the surface,
49
+ * so this is how a garment is kept off a body it would otherwise graze —
50
+ * the same idea as `FluidObstacle#inflation`, and useful for the same
51
+ * reason: a collider that approximates a limb loosely wants the cloth held
52
+ * a little further out than the approximation.
53
+ * @type {number}
54
+ */
55
+ inflation = 0;
56
+
57
+ /**
58
+ * Multiplies the entity's `Collider#friction` before it is combined with
59
+ * the cloth's own. `0` makes the surface frictionless to cloth without
60
+ * making it frictionless to rigid bodies, which is the case this exists
61
+ * for: a character's collision capsules are tuned for footing, and a cape
62
+ * that grips them the same way reads as glued.
63
+ * @type {number}
64
+ */
65
+ friction_scale = 1;
66
+
67
+ /**
68
+ * Collision layer this collider belongs to, `RigidBody` semantics.
69
+ * @type {number}
70
+ */
71
+ layer = 1;
72
+
73
+ /**
74
+ * Which `Cloth` layers this collider acts on.
75
+ * @type {number}
76
+ */
77
+ mask = 0xFFFFFFFF;
78
+
79
+ /**
80
+ * @see ClothColliderFlags
81
+ * @type {number}
82
+ */
83
+ flags = ClothColliderFlags.None;
84
+
85
+ /**
86
+ * @param {object} [spec]
87
+ * @param {number} [spec.inflation]
88
+ * @param {number} [spec.friction_scale]
89
+ * @param {number} [spec.layer]
90
+ * @param {number} [spec.mask]
91
+ * @param {number} [spec.flags]
92
+ * @returns {ClothCollider}
93
+ */
94
+ static from(spec = {}) {
95
+ const r = new ClothCollider();
96
+
97
+ const {
98
+ inflation = r.inflation,
99
+ friction_scale = r.friction_scale,
100
+ layer = r.layer,
101
+ mask = r.mask,
102
+ flags = r.flags
103
+ } = spec;
104
+
105
+ assert.isNumber(inflation, 'inflation');
106
+ assert.isNumber(friction_scale, 'friction_scale');
107
+ assert.isNonNegativeInteger(layer, 'layer');
108
+ assert.isNonNegativeInteger(mask, 'mask');
109
+ assert.isNonNegativeInteger(flags, 'flags');
110
+
111
+ r.inflation = inflation;
112
+ r.friction_scale = friction_scale;
113
+ r.layer = layer;
114
+ r.mask = mask;
115
+ r.flags = flags;
116
+
117
+ return r;
118
+ }
119
+
120
+ /**
121
+ * @param {number|ClothColliderFlags} flag
122
+ * @returns {boolean}
123
+ */
124
+ getFlag(flag) {
125
+ return (this.flags & flag) === flag;
126
+ }
127
+
128
+ /**
129
+ * @param {ClothCollider} other
130
+ * @returns {boolean}
131
+ */
132
+ equals(other) {
133
+ if (other === this) {
134
+ return true;
135
+ }
136
+
137
+ if (other === null || other === undefined || other.isClothCollider !== true) {
138
+ return false;
139
+ }
140
+
141
+ return this.inflation === other.inflation
142
+ && this.friction_scale === other.friction_scale
143
+ && this.layer === other.layer
144
+ && this.mask === other.mask
145
+ && this.flags === other.flags;
146
+ }
147
+
148
+ /**
149
+ * @returns {number}
150
+ */
151
+ hash() {
152
+ return combine_hash(
153
+ computeHashFloat(this.inflation),
154
+ computeHashFloat(this.friction_scale),
155
+ this.layer,
156
+ this.mask,
157
+ this.flags
158
+ );
159
+ }
160
+
161
+ toJSON() {
162
+ return {
163
+ inflation: this.inflation,
164
+ friction_scale: this.friction_scale,
165
+ layer: this.layer,
166
+ mask: this.mask,
167
+ flags: this.flags
168
+ };
169
+ }
170
+
171
+ /**
172
+ * @param {object} json
173
+ */
174
+ fromJSON({
175
+ inflation = 0,
176
+ friction_scale = 1,
177
+ layer = 1,
178
+ mask = 0xFFFFFFFF,
179
+ flags = ClothColliderFlags.None
180
+ }) {
181
+ this.inflation = inflation;
182
+ this.friction_scale = friction_scale;
183
+ this.layer = layer;
184
+ this.mask = mask;
185
+ this.flags = flags;
186
+ }
187
+
188
+ toString() {
189
+ return `ClothCollider${JSON.stringify(this.toJSON())}`;
190
+ }
191
+ }
192
+
193
+ /**
194
+ * @readonly
195
+ * @type {boolean}
196
+ */
197
+ ClothCollider.prototype.isClothCollider = true;
198
+
199
+ ClothCollider.typeName = "ClothCollider";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * *
3
+ */
4
+ export type ClothColliderFlags = number;
5
+ export namespace ClothColliderFlags {
6
+ let None: number;
7
+ let Static: number;
8
+ }
9
+ //# sourceMappingURL=ClothColliderFlags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothColliderFlags.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothColliderFlags.js"],"names":[],"mappings":";;;iCAIU,MAAM"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Switches on {@link ClothCollider}.
3
+ *
4
+ * @readonly
5
+ * @enum {number}
6
+ *
7
+ * @author Alex Goldring
8
+ * @copyright Company Named Limited (c) 2026
9
+ */
10
+ export const ClothColliderFlags = {
11
+ None: 0,
12
+
13
+ /**
14
+ * The collider never moves, so it is placed once and never swept.
15
+ *
16
+ * §8.2's swept collision interpolates each collider's pose between the
17
+ * previous step's and this one's, and rolling one pose into the other and
18
+ * refitting the swept bounds is the per-collider, per-step cost of that. A
19
+ * ground plane, a wall, a rock pays it for nothing, and a large static
20
+ * collider pays the most because its bounds are the biggest thing the
21
+ * broadphase tests against.
22
+ *
23
+ * Set this and the pose is written once, at link, into **both** slots, so
24
+ * the sweep degenerates to the pose it already had. Move the entity anyway
25
+ * and the cloth will not notice: that is the trade, and it is why this is
26
+ * an author's assertion rather than something derived from a pose that
27
+ * happens not to have changed yet.
28
+ */
29
+ Static: 1
30
+ };
31
+
32
+ Object.freeze(ClothColliderFlags);
@@ -0,0 +1,114 @@
1
+ /**
2
+ * # The index's owner
3
+ *
4
+ * Observes `(ClothCollider, Collider, Transform64)` and maintains a
5
+ * {@link ClothColliderIndex}. The same shape as
6
+ * `AcousticOccluderIndex`/`OccluderBody` in the sound simulation, and for the
7
+ * same reason: the consumer needs a compact, pose-cached, broadphase-able view
8
+ * of a set of colliders that is deliberately not the physics BVH, because
9
+ * `ColliderObserverSystem` skips colliders with no owning body and a
10
+ * character's bone colliders have none.
11
+ *
12
+ * ## It has no `fixedUpdate`, and that is §4.1 applied a second time
13
+ *
14
+ * The index has to be refreshed from the world's transforms **before** any
15
+ * cloth reads it, and the engine's two ordering mechanisms cannot express that:
16
+ * `updateExecutionOrder` scores a system as a sum over the components it
17
+ * references and sorts descending, so a system can only be moved *earlier* by
18
+ * touching more, and `ClothSystem` — which reads and writes `Transform64` and
19
+ * `TransformAttachment` — outscores a system that only reads. Registration
20
+ * order does not break a non-tie.
21
+ *
22
+ * §4.1's conclusion applies unchanged: the answer is not a third mechanism, it
23
+ * is not needing one. So this system does not step at all. {@link refresh} is
24
+ * called once, at the top of `ClothSystem#fixedUpdate`, before any cloth is
25
+ * advanced — one call site, no flag to keep true, and the collider poses are
26
+ * read at exactly the moment the anchor poses are, which is what makes a
27
+ * contact consistent rather than merely fresh.
28
+ *
29
+ * The consequence, stated: with no `ClothSystem` in the manager the index is
30
+ * never refreshed. Nothing reads it either, so the cost of that is zero and the
31
+ * alternative — refreshing on a schedule nobody consumes — is worse.
32
+ *
33
+ * ## A mesh collider is skipped, once, loudly
34
+ *
35
+ * §8.2 restricts cloth to analytic primitives, which is universal in shipping
36
+ * cloth systems and is what makes the inner loop arithmetic rather than a BVH
37
+ * descent. A `Collider` carrying a mesh or a heightmap is skipped with one
38
+ * warning naming the entity, and the documented answer is to add primitive
39
+ * `ClothCollider` children — which is what an author would do for a character
40
+ * anyway.
41
+ *
42
+ * @author Alex Goldring
43
+ * @copyright Company Named Limited (c) 2026
44
+ */
45
+ export class ClothColliderSystem extends System<any> {
46
+ constructor();
47
+ dependencies: (typeof Transform64 | typeof Collider | typeof ClothCollider)[];
48
+ components_used: (ResourceAccessSpecification<typeof Transform64> | ResourceAccessSpecification<typeof Collider> | ResourceAccessSpecification<typeof ClothCollider>)[];
49
+ /**
50
+ * @type {ClothColliderIndex}
51
+ */
52
+ index: ClothColliderIndex;
53
+ /**
54
+ * Handle in {@link index} per linked entity. An entity whose shape cloth
55
+ * cannot collide against is absent rather than present with `-1`, so the
56
+ * refresh loop iterates only over colliders that exist.
57
+ * @type {Map<number, number>}
58
+ * @private
59
+ */
60
+ private __handles;
61
+ /**
62
+ * Live `(ClothCollider, Collider, Transform64)` per handle, in the order
63
+ * they were linked. Held rather than looked up per step for the same reason
64
+ * `ClothInstance` holds its transforms: a refresh is a loop over live
65
+ * colliders, not a query.
66
+ * @type {{collider: ClothCollider, transform: Transform64, entity: number, handle: number}[]}
67
+ * @private
68
+ */
69
+ private __linked;
70
+ /**
71
+ * @param {ClothCollider} cloth_collider
72
+ * @param {Collider} collider
73
+ * @param {Transform64} transform
74
+ * @param {number} entity
75
+ */
76
+ link(cloth_collider: ClothCollider, collider: Collider, transform: Transform64, entity: number): void;
77
+ /**
78
+ * @param {ClothCollider} cloth_collider
79
+ * @param {Collider} collider
80
+ * @param {Transform64} transform
81
+ * @param {number} entity
82
+ */
83
+ unlink(cloth_collider: ClothCollider, collider: Collider, transform: Transform64, entity: number): void;
84
+ /**
85
+ * Roll every collider's pose forward one fixed step and re-read it from the
86
+ * world. Called by `ClothSystem` at the top of its own fixed update; see the
87
+ * class docblock for why it is a call rather than an ordering.
88
+ *
89
+ * @returns {void}
90
+ */
91
+ refresh(): void;
92
+ /**
93
+ * Re-read a collider's surface and filter from its components. An author
94
+ * changing `inflation` or a layer at runtime says so here; nothing polls
95
+ * for it, which is the same contract `ClothSystem#reseed` carries for a
96
+ * structural change.
97
+ *
98
+ * @param {number} entity
99
+ * @returns {void}
100
+ */
101
+ refreshSurface(entity: number): void;
102
+ /**
103
+ * @param {number} entity
104
+ * @returns {number} the index handle, or `undefined` if the entity is not indexed
105
+ */
106
+ handleOf(entity: number): number;
107
+ }
108
+ import { System } from "../../../ecs/System.js";
109
+ import { Transform64 } from "../../../ecs/transform/Transform64.js";
110
+ import { Collider } from "../../ecs/Collider.js";
111
+ import { ClothCollider } from "./ClothCollider.js";
112
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
113
+ import { ClothColliderIndex } from "../collider/ClothColliderIndex.js";
114
+ //# sourceMappingURL=ClothColliderSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClothColliderSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/physics/cloth/ecs/ClothColliderSystem.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH;;IAEI,8EAAsD;IAEtD,wKAIE;IAEF;;OAEG;IACH,OAFU,kBAAkB,CAEK;IAEjC;;;;;;OAMG;IACH,kBAAsB;IAEtB;;;;;;;OAOG;IACH,iBAAc;IAEd;;;;;OAKG;IACH,qBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAsChB;IAED;;;;;OAKG;IACH,uBALW,aAAa,YACb,QAAQ,aACR,WAAW,UACX,MAAM,QAmBhB;IAED;;;;;;OAMG;IACH,WAFa,IAAI,CAkChB;IAED;;;;;;;;OAQG;IACH,uBAHW,MAAM,GACJ,IAAI,CAyBhB;IAED;;;OAGG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;CACJ;uBAhPsB,wBAAwB;4BAKxC,uCAAuC;yBACrB,uBAAuB;8BAElB,oBAAoB;4CATN,uDAAuD;mCAQhE,mCAAmC"}
@@ -0,0 +1,243 @@
1
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
2
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
3
+ import { System } from "../../../ecs/System.js";
4
+ import {
5
+ TRANSFORM64_ROTATION_OFFSET,
6
+ TRANSFORM64_TRANSLATION_OFFSET,
7
+ Transform64
8
+ } from "../../../ecs/transform/Transform64.js";
9
+ import { Collider } from "../../ecs/Collider.js";
10
+ import { ClothColliderIndex } from "../collider/ClothColliderIndex.js";
11
+ import { ClothCollider } from "./ClothCollider.js";
12
+ import { ClothColliderFlags } from "./ClothColliderFlags.js";
13
+
14
+ /**
15
+ * # The index's owner
16
+ *
17
+ * Observes `(ClothCollider, Collider, Transform64)` and maintains a
18
+ * {@link ClothColliderIndex}. The same shape as
19
+ * `AcousticOccluderIndex`/`OccluderBody` in the sound simulation, and for the
20
+ * same reason: the consumer needs a compact, pose-cached, broadphase-able view
21
+ * of a set of colliders that is deliberately not the physics BVH, because
22
+ * `ColliderObserverSystem` skips colliders with no owning body and a
23
+ * character's bone colliders have none.
24
+ *
25
+ * ## It has no `fixedUpdate`, and that is §4.1 applied a second time
26
+ *
27
+ * The index has to be refreshed from the world's transforms **before** any
28
+ * cloth reads it, and the engine's two ordering mechanisms cannot express that:
29
+ * `updateExecutionOrder` scores a system as a sum over the components it
30
+ * references and sorts descending, so a system can only be moved *earlier* by
31
+ * touching more, and `ClothSystem` — which reads and writes `Transform64` and
32
+ * `TransformAttachment` — outscores a system that only reads. Registration
33
+ * order does not break a non-tie.
34
+ *
35
+ * §4.1's conclusion applies unchanged: the answer is not a third mechanism, it
36
+ * is not needing one. So this system does not step at all. {@link refresh} is
37
+ * called once, at the top of `ClothSystem#fixedUpdate`, before any cloth is
38
+ * advanced — one call site, no flag to keep true, and the collider poses are
39
+ * read at exactly the moment the anchor poses are, which is what makes a
40
+ * contact consistent rather than merely fresh.
41
+ *
42
+ * The consequence, stated: with no `ClothSystem` in the manager the index is
43
+ * never refreshed. Nothing reads it either, so the cost of that is zero and the
44
+ * alternative — refreshing on a schedule nobody consumes — is worse.
45
+ *
46
+ * ## A mesh collider is skipped, once, loudly
47
+ *
48
+ * §8.2 restricts cloth to analytic primitives, which is universal in shipping
49
+ * cloth systems and is what makes the inner loop arithmetic rather than a BVH
50
+ * descent. A `Collider` carrying a mesh or a heightmap is skipped with one
51
+ * warning naming the entity, and the documented answer is to add primitive
52
+ * `ClothCollider` children — which is what an author would do for a character
53
+ * anyway.
54
+ *
55
+ * @author Alex Goldring
56
+ * @copyright Company Named Limited (c) 2026
57
+ */
58
+ export class ClothColliderSystem extends System {
59
+
60
+ dependencies = [ClothCollider, Collider, Transform64];
61
+
62
+ components_used = [
63
+ ResourceAccessSpecification.from(ClothCollider, ResourceAccessKind.Read),
64
+ ResourceAccessSpecification.from(Collider, ResourceAccessKind.Read),
65
+ ResourceAccessSpecification.from(Transform64, ResourceAccessKind.Read)
66
+ ];
67
+
68
+ /**
69
+ * @type {ClothColliderIndex}
70
+ */
71
+ index = new ClothColliderIndex();
72
+
73
+ /**
74
+ * Handle in {@link index} per linked entity. An entity whose shape cloth
75
+ * cannot collide against is absent rather than present with `-1`, so the
76
+ * refresh loop iterates only over colliders that exist.
77
+ * @type {Map<number, number>}
78
+ * @private
79
+ */
80
+ __handles = new Map();
81
+
82
+ /**
83
+ * Live `(ClothCollider, Collider, Transform64)` per handle, in the order
84
+ * they were linked. Held rather than looked up per step for the same reason
85
+ * `ClothInstance` holds its transforms: a refresh is a loop over live
86
+ * colliders, not a query.
87
+ * @type {{collider: ClothCollider, transform: Transform64, entity: number, handle: number}[]}
88
+ * @private
89
+ */
90
+ __linked = [];
91
+
92
+ /**
93
+ * @param {ClothCollider} cloth_collider
94
+ * @param {Collider} collider
95
+ * @param {Transform64} transform
96
+ * @param {number} entity
97
+ */
98
+ link(cloth_collider, collider, transform, entity) {
99
+ const handle = this.index.add(
100
+ collider.shape,
101
+ collider.friction * cloth_collider.friction_scale,
102
+ cloth_collider.inflation,
103
+ cloth_collider.layer,
104
+ cloth_collider.mask,
105
+ entity
106
+ );
107
+
108
+ if (handle < 0) {
109
+ console.warn(
110
+ `ClothColliderSystem: entity ${entity} carries a ${collider.shape.constructor.name}, `
111
+ + `which cloth does not collide against (§8.2 — analytic primitives only). `
112
+ + `Add primitive ClothCollider children instead.`
113
+ );
114
+
115
+ return;
116
+ }
117
+
118
+ this.__handles.set(entity, handle);
119
+
120
+ this.__linked.push({ collider: cloth_collider, transform, entity, handle });
121
+
122
+ // Placed rather than posed, so its first step sweeps nothing. A
123
+ // collider that has just appeared did not move.
124
+ this.index.placePose(
125
+ handle,
126
+ transform[TRANSFORM64_TRANSLATION_OFFSET],
127
+ transform[TRANSFORM64_TRANSLATION_OFFSET + 1],
128
+ transform[TRANSFORM64_TRANSLATION_OFFSET + 2],
129
+ transform[TRANSFORM64_ROTATION_OFFSET],
130
+ transform[TRANSFORM64_ROTATION_OFFSET + 1],
131
+ transform[TRANSFORM64_ROTATION_OFFSET + 2],
132
+ transform[TRANSFORM64_ROTATION_OFFSET + 3]
133
+ );
134
+ }
135
+
136
+ /**
137
+ * @param {ClothCollider} cloth_collider
138
+ * @param {Collider} collider
139
+ * @param {Transform64} transform
140
+ * @param {number} entity
141
+ */
142
+ unlink(cloth_collider, collider, transform, entity) {
143
+ const handle = this.__handles.get(entity);
144
+
145
+ if (handle === undefined) {
146
+ return;
147
+ }
148
+
149
+ this.__handles.delete(entity);
150
+ this.index.remove(handle);
151
+
152
+ for (let i = 0; i < this.__linked.length; i++) {
153
+ if (this.__linked[i].entity === entity) {
154
+ this.__linked.splice(i, 1);
155
+
156
+ break;
157
+ }
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Roll every collider's pose forward one fixed step and re-read it from the
163
+ * world. Called by `ClothSystem` at the top of its own fixed update; see the
164
+ * class docblock for why it is a call rather than an ordering.
165
+ *
166
+ * @returns {void}
167
+ */
168
+ refresh() {
169
+ const index = this.index;
170
+
171
+ index.advance();
172
+
173
+ const linked = this.__linked;
174
+
175
+ for (let i = 0; i < linked.length; i++) {
176
+ const entry = linked[i];
177
+
178
+ const cloth_collider = entry.collider;
179
+
180
+ if ((cloth_collider.flags & ClothColliderFlags.Static) !== 0) {
181
+ // Placed once at link and never swept. `advance` has just made
182
+ // its previous pose equal to its current one, which is exactly
183
+ // the state a static collider wants and costs nothing to leave.
184
+ continue;
185
+ }
186
+
187
+ const transform = entry.transform;
188
+
189
+ index.setPose(
190
+ entry.handle,
191
+ transform[TRANSFORM64_TRANSLATION_OFFSET],
192
+ transform[TRANSFORM64_TRANSLATION_OFFSET + 1],
193
+ transform[TRANSFORM64_TRANSLATION_OFFSET + 2],
194
+ transform[TRANSFORM64_ROTATION_OFFSET],
195
+ transform[TRANSFORM64_ROTATION_OFFSET + 1],
196
+ transform[TRANSFORM64_ROTATION_OFFSET + 2],
197
+ transform[TRANSFORM64_ROTATION_OFFSET + 3]
198
+ );
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Re-read a collider's surface and filter from its components. An author
204
+ * changing `inflation` or a layer at runtime says so here; nothing polls
205
+ * for it, which is the same contract `ClothSystem#reseed` carries for a
206
+ * structural change.
207
+ *
208
+ * @param {number} entity
209
+ * @returns {void}
210
+ */
211
+ refreshSurface(entity) {
212
+ const handle = this.__handles.get(entity);
213
+
214
+ if (handle === undefined) {
215
+ return;
216
+ }
217
+
218
+ const ecd = this.entityManager.dataset;
219
+
220
+ const cloth_collider = ecd.getComponent(entity, ClothCollider);
221
+ const collider = ecd.getComponent(entity, Collider);
222
+
223
+ if (cloth_collider === undefined || collider === undefined) {
224
+ return;
225
+ }
226
+
227
+ this.index.setSurface(
228
+ handle,
229
+ collider.friction * cloth_collider.friction_scale,
230
+ cloth_collider.inflation
231
+ );
232
+
233
+ this.index.setFilter(handle, cloth_collider.layer, cloth_collider.mask);
234
+ }
235
+
236
+ /**
237
+ * @param {number} entity
238
+ * @returns {number} the index handle, or `undefined` if the entity is not indexed
239
+ */
240
+ handleOf(entity) {
241
+ return this.__handles.get(entity);
242
+ }
243
+ }