@woosh/meep-engine 3.38.0 → 3.39.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 (962) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/binary/BinaryBuffer.d.ts +11 -0
  5. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  6. package/src/core/binary/BinaryBuffer.js +30 -0
  7. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_aabb.d.ts.map +1 -1
  8. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_aabb.js +28 -7
  9. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts +15 -0
  10. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -1
  11. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +41 -0
  12. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts +12 -0
  13. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.d.ts.map +1 -1
  14. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.js +27 -0
  15. package/src/core/geom/3d/gjk/gjk.js +3 -3
  16. package/src/core/geom/3d/gjk/gjk_distance.d.ts +94 -0
  17. package/src/core/geom/3d/gjk/gjk_distance.d.ts.map +1 -0
  18. package/src/core/geom/3d/gjk/gjk_distance.js +782 -0
  19. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts +5 -4
  20. package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -1
  21. package/src/core/geom/3d/gjk/gjk_epa_penetration.js +14 -9
  22. package/src/core/geom/3d/gjk/minkowski_support.d.ts +11 -7
  23. package/src/core/geom/3d/gjk/minkowski_support.d.ts.map +1 -1
  24. package/src/core/geom/3d/gjk/minkowski_support.js +33 -9
  25. package/src/core/geom/3d/gjk/mpr.d.ts.map +1 -1
  26. package/src/core/geom/3d/gjk/mpr.js +26 -5
  27. package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.d.ts +15 -0
  28. package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.d.ts.map +1 -1
  29. package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.js +106 -33
  30. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts +2 -1
  31. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts.map +1 -1
  32. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +4 -8
  33. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_array.d.ts +32 -0
  34. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_array.d.ts.map +1 -0
  35. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_array.js +85 -0
  36. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.d.ts +3 -3
  37. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.d.ts.map +1 -1
  38. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.js +24 -34
  39. package/src/core/geom/3d/quaternion/quat3_integrate.d.ts +17 -0
  40. package/src/core/geom/3d/quaternion/quat3_integrate.d.ts.map +1 -1
  41. package/src/core/geom/3d/quaternion/quat3_integrate.js +45 -4
  42. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts +16 -0
  43. package/src/core/geom/3d/quaternion/quat3_multiply.d.ts.map +1 -1
  44. package/src/core/geom/3d/quaternion/quat3_multiply.js +25 -0
  45. package/src/core/geom/3d/quaternion/quat3_nlerp.d.ts +18 -0
  46. package/src/core/geom/3d/quaternion/quat3_nlerp.d.ts.map +1 -1
  47. package/src/core/geom/3d/quaternion/quat3_nlerp.js +45 -0
  48. package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts +17 -0
  49. package/src/core/geom/3d/quaternion/quat3_shortest_arc.d.ts.map +1 -1
  50. package/src/core/geom/3d/quaternion/quat3_shortest_arc.js +155 -94
  51. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts +12 -0
  52. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts.map +1 -1
  53. package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +31 -0
  54. package/src/core/geom/3d/shape/AbstractShape3D.d.ts +20 -6
  55. package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
  56. package/src/core/geom/3d/shape/AbstractShape3D.js +20 -6
  57. package/src/core/geom/3d/shape/BoxShape3D.d.ts +1 -1
  58. package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
  59. package/src/core/geom/3d/shape/BoxShape3D.js +5 -1
  60. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +1 -1
  61. package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
  62. package/src/core/geom/3d/shape/CapsuleShape3D.js +5 -1
  63. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +25 -11
  64. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  65. package/src/core/geom/3d/shape/ConvexHullShape3D.js +392 -22
  66. package/src/core/geom/3d/shape/CylinderShape3D.d.ts +8 -7
  67. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  68. package/src/core/geom/3d/shape/CylinderShape3D.js +12 -7
  69. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +51 -8
  70. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  71. package/src/core/geom/3d/shape/HeightMapShape3D.js +260 -14
  72. package/src/core/geom/3d/shape/MeshShape3D.d.ts +61 -7
  73. package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -1
  74. package/src/core/geom/3d/shape/MeshShape3D.js +111 -20
  75. package/src/core/geom/3d/shape/PointShape3D.d.ts +1 -1
  76. package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
  77. package/src/core/geom/3d/shape/PointShape3D.js +1 -1
  78. package/src/core/geom/3d/shape/PosedShape3D.d.ts +9 -0
  79. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  80. package/src/core/geom/3d/shape/PosedShape3D.js +36 -6
  81. package/src/core/geom/3d/shape/SphereShape3D.d.ts +1 -1
  82. package/src/core/geom/3d/shape/SphereShape3D.d.ts.map +1 -1
  83. package/src/core/geom/3d/shape/SphereShape3D.js +5 -1
  84. package/src/core/geom/3d/shape/TransformedShape3D.d.ts +12 -10
  85. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  86. package/src/core/geom/3d/shape/TransformedShape3D.js +53 -19
  87. package/src/core/geom/3d/shape/Triangle3D.d.ts +1 -1
  88. package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -1
  89. package/src/core/geom/3d/shape/Triangle3D.js +5 -1
  90. package/src/core/geom/3d/shape/UnionShape3D.d.ts +1 -1
  91. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  92. package/src/core/geom/3d/shape/UnionShape3D.js +19 -2
  93. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +14 -0
  94. package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -1
  95. package/src/core/geom/3d/shape/sdf/sdf3_box.js +67 -5
  96. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +14 -0
  97. package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -1
  98. package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +61 -3
  99. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +14 -0
  100. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -1
  101. package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +63 -4
  102. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +15 -0
  103. package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -1
  104. package/src/core/geom/3d/shape/sdf/sdf3_plane.js +64 -2
  105. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +21 -0
  106. package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -1
  107. package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +66 -3
  108. package/src/core/geom/3d/shape/shape3_mesh_from_geometry.d.ts +2 -0
  109. package/src/core/geom/3d/shape/shape3_mesh_from_geometry.d.ts.map +1 -1
  110. package/src/core/geom/3d/shape/shape3_mesh_from_geometry.js +7 -0
  111. package/src/core/geom/3d/shape/util/mesh_compute_triangle_edge_flags.d.ts +41 -0
  112. package/src/core/geom/3d/shape/util/mesh_compute_triangle_edge_flags.d.ts.map +1 -0
  113. package/src/core/geom/3d/shape/util/mesh_compute_triangle_edge_flags.js +538 -0
  114. package/src/core/geom/3d/sphere/harmonics/sh_basis_at.d.ts +31 -0
  115. package/src/core/geom/3d/sphere/harmonics/sh_basis_at.d.ts.map +1 -0
  116. package/src/core/geom/3d/sphere/harmonics/sh_basis_at.js +85 -0
  117. package/src/core/geom/3d/sphere/harmonics/sh_vmf_window.d.ts +18 -0
  118. package/src/core/geom/3d/sphere/harmonics/sh_vmf_window.d.ts.map +1 -0
  119. package/src/core/geom/3d/sphere/harmonics/sh_vmf_window.js +19 -0
  120. package/src/core/geom/3d/triangle/TriangleEdgeFlags.d.ts +49 -0
  121. package/src/core/geom/3d/triangle/TriangleEdgeFlags.d.ts.map +1 -0
  122. package/src/core/geom/3d/triangle/TriangleEdgeFlags.js +55 -0
  123. package/src/core/geom/3d/triangle/tri3_classify_shared_edge.d.ts +42 -0
  124. package/src/core/geom/3d/triangle/tri3_classify_shared_edge.d.ts.map +1 -0
  125. package/src/core/geom/3d/triangle/tri3_classify_shared_edge.js +85 -0
  126. package/src/core/geom/3d/triangle/tri3_closest_point.d.ts +13 -0
  127. package/src/core/geom/3d/triangle/tri3_closest_point.d.ts.map +1 -1
  128. package/src/core/geom/3d/triangle/tri3_closest_point.js +36 -1
  129. package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.d.ts +14 -0
  130. package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.d.ts.map +1 -1
  131. package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.js +40 -0
  132. package/src/core/geom/vec3/v3_quaternion_apply.d.ts +19 -0
  133. package/src/core/geom/vec3/v3_quaternion_apply.d.ts.map +1 -1
  134. package/src/core/geom/vec3/v3_quaternion_apply.js +32 -0
  135. package/src/core/geom/vec3/v3_quaternion_apply_inverse.d.ts +19 -0
  136. package/src/core/geom/vec3/v3_quaternion_apply_inverse.d.ts.map +1 -1
  137. package/src/core/geom/vec3/v3_quaternion_apply_inverse.js +32 -0
  138. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +135 -10
  139. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  140. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +338 -105
  141. package/src/engine/control/first-person/abilities/Ability.d.ts +14 -5
  142. package/src/engine/control/first-person/abilities/Ability.d.ts.map +1 -1
  143. package/src/engine/control/first-person/abilities/Ability.js +14 -5
  144. package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
  145. package/src/engine/control/first-person/abilities/LedgeGrab.js +16 -12
  146. package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
  147. package/src/engine/control/first-person/abilities/Mantle.js +5 -1
  148. package/src/engine/control/first-person/abilities/Slide.js +1 -1
  149. package/src/engine/control/first-person/collision/KinematicMover.d.ts +92 -14
  150. package/src/engine/control/first-person/collision/KinematicMover.d.ts.map +1 -1
  151. package/src/engine/control/first-person/collision/KinematicMover.js +218 -37
  152. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +5 -0
  153. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
  154. package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +17 -10
  155. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  156. package/src/engine/ecs/EntityComponentDataset.js +27 -13
  157. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  158. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  159. package/src/engine/ecs/transform/Transform64.d.ts +4 -2
  160. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
  161. package/src/engine/ecs/transform/Transform64.js +10 -16
  162. package/src/engine/graphics/ecs/water/Water.d.ts +25 -63
  163. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  164. package/src/engine/graphics/ecs/water/Water.js +110 -125
  165. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
  166. package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +38 -74
  167. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.d.ts +1 -1
  168. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.d.ts.map +1 -1
  169. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_1_2.js +27 -18
  170. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_2_3.d.ts +12 -0
  171. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_2_3.d.ts.map +1 -0
  172. package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_2_3.js +45 -0
  173. package/src/engine/graphics/ecs/water/WaterWaves.d.ts +33 -0
  174. package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -0
  175. package/src/engine/graphics/ecs/water/WaterWaves.js +46 -0
  176. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts +17 -0
  177. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -0
  178. package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +26 -0
  179. package/src/engine/graphics/texture/3d/scs3d_sample_linear.d.ts +22 -0
  180. package/src/engine/graphics/texture/3d/scs3d_sample_linear.d.ts.map +1 -1
  181. package/src/engine/graphics/texture/3d/scs3d_sample_linear.js +43 -1
  182. package/src/engine/graphics/texture/sampler/Sampler2D.d.ts +29 -3
  183. package/src/engine/graphics/texture/sampler/Sampler2D.d.ts.map +1 -1
  184. package/src/engine/graphics/texture/sampler/Sampler2D.js +102 -14
  185. package/src/engine/graphics3/WaterSystem.d.ts +39 -3
  186. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  187. package/src/engine/graphics3/WaterSystem.js +134 -25
  188. package/src/engine/interpolation/BinaryInterpolationAdapter.d.ts +10 -4
  189. package/src/engine/interpolation/BinaryInterpolationAdapter.d.ts.map +1 -1
  190. package/src/engine/interpolation/BinaryInterpolationAdapter.js +11 -5
  191. package/src/engine/interpolation/InterpolationLog.d.ts +11 -5
  192. package/src/engine/interpolation/InterpolationLog.d.ts.map +1 -1
  193. package/src/engine/interpolation/InterpolationLog.js +12 -6
  194. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  195. package/src/engine/interpolation/InterpolationSystem.js +39 -8
  196. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts +1 -1
  197. package/src/engine/interpolation/PoseInterpolationAdapter.d.ts.map +1 -1
  198. package/src/engine/interpolation/PoseInterpolationAdapter.js +51 -22
  199. package/src/engine/interpolation/TransformPoseSerializationAdapter.d.ts.map +1 -1
  200. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +18 -23
  201. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts +1 -1
  202. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts.map +1 -1
  203. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +3 -1
  204. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts +1 -1
  205. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts.map +1 -1
  206. package/src/engine/network/adapters/TransformInterpolationAdapter.js +3 -1
  207. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts.map +1 -1
  208. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +5 -2
  209. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
  210. package/src/engine/physics/body/SolverBodyState.js +4 -5
  211. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +12 -0
  212. package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -1
  213. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +28 -3
  214. package/src/engine/physics/ccd/linear_sweep.d.ts +42 -12
  215. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  216. package/src/engine/physics/ccd/linear_sweep.js +1131 -97
  217. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +13 -0
  218. package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -1
  219. package/src/engine/physics/cloth/collider/ClothColliderIndex.js +90 -22
  220. package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +84 -24
  221. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +46 -3
  222. package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -1
  223. package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +116 -68
  224. package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
  225. package/src/engine/physics/cloth/ecs/ClothWorld.js +59 -47
  226. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -1
  227. package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +62 -55
  228. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -1
  229. package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +46 -39
  230. package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
  231. package/src/engine/physics/cloth/ecs/cloth_write_back.js +41 -36
  232. package/src/engine/physics/cloth/playground/garment_build.js +6 -6
  233. package/src/engine/physics/cloth/playground/garment_main.js +18 -14
  234. package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -1
  235. package/src/engine/physics/cloth/solver/cloth_contact_find.js +8 -5
  236. package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
  237. package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +8 -5
  238. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -1
  239. package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +15 -15
  240. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts +5 -0
  241. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.d.ts.map +1 -1
  242. package/src/engine/physics/cloth/solver/find_non_finite_cloth_state.js +32 -9
  243. package/src/engine/physics/constraint/solve_constraints.d.ts +50 -8
  244. package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
  245. package/src/engine/physics/constraint/solve_constraints.js +703 -429
  246. package/src/engine/physics/contact/ManifoldStore.d.ts +12 -0
  247. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  248. package/src/engine/physics/contact/ManifoldStore.js +32 -0
  249. package/src/engine/physics/ecs/BodyKind.d.ts +16 -8
  250. package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -1
  251. package/src/engine/physics/ecs/BodyKind.js +16 -8
  252. package/src/engine/physics/ecs/Collider.d.ts +7 -2
  253. package/src/engine/physics/ecs/Collider.d.ts.map +1 -1
  254. package/src/engine/physics/ecs/Collider.js +7 -2
  255. package/src/engine/physics/ecs/PhysicsEvents.d.ts +13 -0
  256. package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -1
  257. package/src/engine/physics/ecs/PhysicsEvents.js +13 -0
  258. package/src/engine/physics/ecs/PhysicsSystem.d.ts +320 -36
  259. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  260. package/src/engine/physics/ecs/PhysicsSystem.js +779 -81
  261. package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
  262. package/src/engine/physics/fluid/FluidField.js +5 -1
  263. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +11 -9
  264. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts.map +1 -1
  265. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +7 -5
  266. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.d.ts.map +1 -1
  267. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +9 -7
  268. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -1
  269. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +3 -4
  270. package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
  271. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +9 -7
  272. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.d.ts.map +1 -1
  273. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +65 -43
  274. package/src/engine/physics/inertia/MASS_PROPERTIES_SIZE.d.ts +23 -0
  275. package/src/engine/physics/inertia/MASS_PROPERTIES_SIZE.d.ts.map +1 -0
  276. package/src/engine/physics/inertia/MASS_PROPERTIES_SIZE.js +22 -0
  277. package/src/engine/physics/inertia/convex_hull_mass_properties.d.ts +29 -0
  278. package/src/engine/physics/inertia/convex_hull_mass_properties.d.ts.map +1 -0
  279. package/src/engine/physics/inertia/convex_hull_mass_properties.js +117 -0
  280. package/src/engine/physics/inertia/mass_properties_accumulate.d.ts +24 -0
  281. package/src/engine/physics/inertia/mass_properties_accumulate.d.ts.map +1 -0
  282. package/src/engine/physics/inertia/mass_properties_accumulate.js +93 -0
  283. package/src/engine/physics/inertia/primitive_mass_properties.d.ts +46 -0
  284. package/src/engine/physics/inertia/primitive_mass_properties.d.ts.map +1 -0
  285. package/src/engine/physics/inertia/primitive_mass_properties.js +118 -0
  286. package/src/engine/physics/inertia/rigid_body_set_mass_properties.d.ts +27 -0
  287. package/src/engine/physics/inertia/rigid_body_set_mass_properties.d.ts.map +1 -0
  288. package/src/engine/physics/inertia/rigid_body_set_mass_properties.js +62 -0
  289. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +67 -25
  290. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  291. package/src/engine/physics/inertia/world_inverse_inertia.js +149 -26
  292. package/src/engine/physics/integration/integrate_position.d.ts +18 -19
  293. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  294. package/src/engine/physics/integration/integrate_position.js +40 -37
  295. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  296. package/src/engine/physics/integration/integrate_velocity.js +13 -4
  297. package/src/engine/physics/island/IslandBuilder.d.ts +124 -6
  298. package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -1
  299. package/src/engine/physics/island/IslandBuilder.js +322 -19
  300. package/src/engine/physics/narrowphase/box_box_manifold.d.ts +13 -0
  301. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  302. package/src/engine/physics/narrowphase/box_box_manifold.js +95 -39
  303. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts +40 -0
  304. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -1
  305. package/src/engine/physics/narrowphase/box_triangle_contact.js +415 -120
  306. package/src/engine/physics/narrowphase/capsule_contacts.d.ts +63 -0
  307. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  308. package/src/engine/physics/narrowphase/capsule_contacts.js +234 -46
  309. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts +13 -0
  310. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -1
  311. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +141 -93
  312. package/src/engine/physics/narrowphase/compute_penetration.d.ts +29 -11
  313. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -1
  314. package/src/engine/physics/narrowphase/compute_penetration.js +157 -34
  315. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts +76 -0
  316. package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
  317. package/src/engine/physics/narrowphase/convex_convex_manifold.js +243 -48
  318. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts +13 -0
  319. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts.map +1 -1
  320. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +28 -12
  321. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +13 -0
  322. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -1
  323. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +27 -0
  324. package/src/engine/physics/narrowphase/decomposition/heightmap_triangle_edge_flags.d.ts +42 -0
  325. package/src/engine/physics/narrowphase/decomposition/heightmap_triangle_edge_flags.d.ts.map +1 -0
  326. package/src/engine/physics/narrowphase/decomposition/heightmap_triangle_edge_flags.js +250 -0
  327. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +27 -11
  328. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -1
  329. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +291 -12
  330. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts +7 -1
  331. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts.map +1 -1
  332. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +7 -1
  333. package/src/engine/physics/narrowphase/decomposition/triangle_edge_flags.d.ts +35 -0
  334. package/src/engine/physics/narrowphase/decomposition/triangle_edge_flags.d.ts.map +1 -0
  335. package/src/engine/physics/narrowphase/decomposition/triangle_edge_flags.js +61 -0
  336. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts +54 -0
  337. package/src/engine/physics/narrowphase/hull_sphere_contact.d.ts.map +1 -0
  338. package/src/engine/physics/narrowphase/hull_sphere_contact.js +244 -0
  339. package/src/engine/physics/narrowphase/mesh_convex_hull.js +5 -1
  340. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.d.ts +2 -0
  341. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.d.ts.map +1 -1
  342. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +56 -31
  343. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +6 -5
  344. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  345. package/src/engine/physics/narrowphase/narrowphase_step.js +2185 -483
  346. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts +56 -5
  347. package/src/engine/physics/narrowphase/reduce_manifold_contacts.d.ts.map +1 -1
  348. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +546 -5
  349. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts +29 -2
  350. package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
  351. package/src/engine/physics/narrowphase/refine_ray_concave.js +628 -75
  352. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +3 -2
  353. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  354. package/src/engine/physics/narrowphase/refine_ray_hit.js +3 -2
  355. package/src/engine/physics/narrowphase/rigid_subject_pose.d.ts +27 -0
  356. package/src/engine/physics/narrowphase/rigid_subject_pose.d.ts.map +1 -0
  357. package/src/engine/physics/narrowphase/rigid_subject_pose.js +96 -0
  358. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts +14 -0
  359. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  360. package/src/engine/physics/narrowphase/sphere_box_contact.js +51 -5
  361. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts +12 -0
  362. package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts.map +1 -1
  363. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +30 -0
  364. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts +12 -0
  365. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts.map +1 -1
  366. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +37 -8
  367. package/src/engine/physics/narrowphase/support_feature_manifold.d.ts +139 -0
  368. package/src/engine/physics/narrowphase/support_feature_manifold.d.ts.map +1 -0
  369. package/src/engine/physics/narrowphase/support_feature_manifold.js +949 -0
  370. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts +32 -13
  371. package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts.map +1 -1
  372. package/src/engine/physics/queries/PhysicsSurfacePoint.js +36 -13
  373. package/src/engine/physics/queries/convex_overlaps_shape.d.ts +27 -0
  374. package/src/engine/physics/queries/convex_overlaps_shape.d.ts.map +1 -0
  375. package/src/engine/physics/queries/convex_overlaps_shape.js +169 -0
  376. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -1
  377. package/src/engine/physics/queries/overlap_shape.js +57 -79
  378. package/src/engine/physics/queries/raycast.d.ts +10 -4
  379. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  380. package/src/engine/physics/queries/raycast.js +133 -9
  381. package/src/engine/physics/queries/shape_cast.d.ts +55 -24
  382. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -1
  383. package/src/engine/physics/queries/shape_cast.js +2061 -245
  384. package/src/engine/physics/solver/apply_impulse_to_body.d.ts +32 -10
  385. package/src/engine/physics/solver/apply_impulse_to_body.d.ts.map +1 -1
  386. package/src/engine/physics/solver/apply_impulse_to_body.js +69 -28
  387. package/src/engine/physics/solver/solve_contacts.d.ts +65 -18
  388. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  389. package/src/engine/physics/solver/solve_contacts.js +458 -234
  390. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  391. package/src/engine/physics/vehicle/RaycastVehicle.js +5 -6
  392. package/src/shade/assets/textures/split_sum.bin +0 -0
  393. package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
  394. package/src/shade/device/mock/SoftwareGPUQueue.js +2 -1
  395. package/src/shade/playground/path_traced_media/README.md +78 -0
  396. package/src/shade/playground/path_traced_media/capture_radiance.d.ts +33 -0
  397. package/src/shade/playground/path_traced_media/capture_radiance.d.ts.map +1 -0
  398. package/src/shade/playground/path_traced_media/capture_radiance.js +174 -0
  399. package/src/shade/playground/path_traced_media/checks.d.ts +160 -0
  400. package/src/shade/playground/path_traced_media/checks.d.ts.map +1 -0
  401. package/src/shade/playground/path_traced_media/checks.js +921 -0
  402. package/src/shade/playground/path_traced_media/index.html +71 -0
  403. package/src/shade/playground/path_traced_media/main.d.ts +2 -0
  404. package/src/shade/playground/path_traced_media/main.d.ts.map +1 -0
  405. package/src/shade/playground/path_traced_media/main.js +440 -0
  406. package/src/shade/playground/path_traced_media/make_wave_pool_geometry.d.ts +26 -0
  407. package/src/shade/playground/path_traced_media/make_wave_pool_geometry.d.ts.map +1 -0
  408. package/src/shade/playground/path_traced_media/make_wave_pool_geometry.js +117 -0
  409. package/src/shade/playground/path_traced_media/views.d.ts +21 -0
  410. package/src/shade/playground/path_traced_media/views.d.ts.map +1 -0
  411. package/src/shade/playground/path_traced_media/views.js +161 -0
  412. package/src/shade/playground/sh_exponential/README.md +43 -0
  413. package/src/shade/playground/sh_exponential/index.html +59 -0
  414. package/src/shade/playground/sh_exponential/main.d.ts +2 -0
  415. package/src/shade/playground/sh_exponential/main.d.ts.map +1 -0
  416. package/src/shade/playground/sh_exponential/main.js +571 -0
  417. package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.d.ts +46 -0
  418. package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.d.ts.map +1 -0
  419. package/src/shade/playground/sh_exponential/sh_exp_playground_shaders.js +270 -0
  420. package/src/shade/playground/water_refraction/README.md +24 -15
  421. package/src/shade/playground/water_refraction/index.html +6 -8
  422. package/src/shade/playground/water_refraction/main.js +12 -11
  423. package/src/shade/playground/water_refraction/world.d.ts +2 -0
  424. package/src/shade/playground/water_refraction/world.d.ts.map +1 -1
  425. package/src/shade/playground/water_refraction/world.js +8 -4
  426. package/src/shade/renderer/Renderer.d.ts +2 -0
  427. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  428. package/src/shade/renderer/Renderer.js +23 -0
  429. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
  430. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +9 -1
  431. package/src/shade/renderer/geometry/sdf/chunk_scene_point_query_volume_sign.d.ts.map +1 -1
  432. package/src/shade/renderer/geometry/sdf/chunk_scene_point_query_volume_sign.js +6 -4
  433. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.d.ts.map +1 -1
  434. package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -0
  435. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_rand1.d.ts +7 -0
  436. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_rand1.d.ts.map +1 -1
  437. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_rand1.js +12 -12
  438. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_spherical.d.ts +4 -0
  439. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_spherical.d.ts.map +1 -1
  440. package/src/shade/renderer/global_illumination/brick4/gpu/bake/sampling/chunk_direction_by_index_spherical.js +13 -9
  441. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  442. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +2 -0
  443. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
  444. package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +3 -0
  445. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.d.ts.map +1 -1
  446. package/src/shade/renderer/global_illumination/lpv/deprecated/probe_trace_compute_shader_code.js +4 -9
  447. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
  448. package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +20 -10
  449. package/src/shade/renderer/light/environment/rgbe/load_environment_map.d.ts +2 -1
  450. package/src/shade/renderer/light/environment/rgbe/load_environment_map.d.ts.map +1 -1
  451. package/src/shade/renderer/light/environment/rgbe/load_environment_map.js +2 -1
  452. package/src/shade/renderer/light/environment/sh_exponential/README.md +171 -0
  453. package/src/shade/renderer/light/environment/sh_exponential/SHExpEncoder.d.ts +170 -0
  454. package/src/shade/renderer/light/environment/sh_exponential/SHExpEncoder.d.ts.map +1 -0
  455. package/src/shade/renderer/light/environment/sh_exponential/SHExpEncoder.js +377 -0
  456. package/src/shade/renderer/light/environment/sh_exponential/SH_EXP_ENCODE_PARAMETERS_STRUCT.d.ts +16 -0
  457. package/src/shade/renderer/light/environment/sh_exponential/SH_EXP_ENCODE_PARAMETERS_STRUCT.d.ts.map +1 -0
  458. package/src/shade/renderer/light/environment/sh_exponential/SH_EXP_ENCODE_PARAMETERS_STRUCT.js +27 -0
  459. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.d.ts +21 -0
  460. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.d.ts.map +1 -0
  461. package/src/shade/renderer/light/environment/sh_exponential/chunk_sh_exp_workgroup_sum.js +53 -0
  462. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_design_row.d.ts +33 -0
  463. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_design_row.d.ts.map +1 -0
  464. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_design_row.js +90 -0
  465. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_fit_samples.d.ts +28 -0
  466. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_fit_samples.d.ts.map +1 -0
  467. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_fit_samples.js +92 -0
  468. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_layout.d.ts +39 -0
  469. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_layout.d.ts.map +1 -0
  470. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_layout.js +44 -0
  471. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_solve_matrix.d.ts +42 -0
  472. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_solve_matrix.d.ts.map +1 -0
  473. package/src/shade/renderer/light/environment/sh_exponential/sh_exp_solve_matrix.js +123 -0
  474. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts +30 -0
  475. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.d.ts.map +1 -0
  476. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_environment_cells.js +147 -0
  477. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_log_floor.d.ts +24 -0
  478. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_log_floor.d.ts.map +1 -0
  479. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_log_floor.js +79 -0
  480. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_project.d.ts +17 -0
  481. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_project.d.ts.map +1 -0
  482. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_project.js +99 -0
  483. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_reference_reflectance.d.ts +24 -0
  484. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_reference_reflectance.d.ts.map +1 -0
  485. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_reference_reflectance.js +104 -0
  486. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_solve.d.ts +12 -0
  487. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_solve.d.ts.map +1 -0
  488. package/src/shade/renderer/light/environment/sh_exponential/shader_sh_exp_solve.js +93 -0
  489. package/src/shade/renderer/lightmap/GPULightMap.d.ts.map +1 -1
  490. package/src/shade/renderer/lightmap/GPULightMap.js +1 -0
  491. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.d.ts.map +1 -1
  492. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_irradiance_flat.js +4 -0
  493. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.d.ts.map +1 -1
  494. package/src/shade/renderer/lightmap/bake/shader_lightmap_viz_to_sh.js +4 -0
  495. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  496. package/src/shade/renderer/material/PIXEL_TEXTURE_ORM.d.ts +1 -1
  497. package/src/shade/renderer/material/PIXEL_TEXTURE_ORM.d.ts.map +1 -1
  498. package/src/shade/renderer/material/StandardShadeMaterial.d.ts +15 -0
  499. package/src/shade/renderer/material/StandardShadeMaterial.d.ts.map +1 -1
  500. package/src/shade/renderer/material/StandardShadeMaterial.js +17 -0
  501. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +36 -2
  502. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  503. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +218 -18
  504. package/src/shade/renderer/material/resident/INDIRECT_MATERIAL_STRUCT.d.ts.map +1 -1
  505. package/src/shade/renderer/material/resident/INDIRECT_MATERIAL_STRUCT.js +10 -0
  506. package/src/shade/renderer/medium/MEDIA_TABLE_STRUCT.d.ts +17 -0
  507. package/src/shade/renderer/medium/MEDIA_TABLE_STRUCT.d.ts.map +1 -0
  508. package/src/shade/renderer/medium/MEDIA_TABLE_STRUCT.js +24 -0
  509. package/src/shade/renderer/medium/MEDIUM_PHASE_LOBE_KIND.d.ts +24 -0
  510. package/src/shade/renderer/medium/MEDIUM_PHASE_LOBE_KIND.d.ts.map +1 -0
  511. package/src/shade/renderer/medium/MEDIUM_PHASE_LOBE_KIND.js +18 -0
  512. package/src/shade/renderer/medium/MEDIUM_STRUCT.d.ts +20 -0
  513. package/src/shade/renderer/medium/MEDIUM_STRUCT.d.ts.map +1 -0
  514. package/src/shade/renderer/medium/MEDIUM_STRUCT.js +43 -0
  515. package/src/shade/renderer/medium/ParticipatingMedium.d.ts +108 -0
  516. package/src/shade/renderer/medium/ParticipatingMedium.d.ts.map +1 -0
  517. package/src/shade/renderer/medium/ParticipatingMedium.js +204 -0
  518. package/src/shade/renderer/medium/chunk_medium_lobe_phase.d.ts +13 -0
  519. package/src/shade/renderer/medium/chunk_medium_lobe_phase.d.ts.map +1 -0
  520. package/src/shade/renderer/medium/chunk_medium_lobe_phase.js +33 -0
  521. package/src/shade/renderer/medium/participating_medium_serialization.d.ts +32 -0
  522. package/src/shade/renderer/medium/participating_medium_serialization.d.ts.map +1 -0
  523. package/src/shade/renderer/medium/participating_medium_serialization.js +181 -0
  524. package/src/shade/renderer/medium/phase/MediumPhaseFunction.d.ts +48 -0
  525. package/src/shade/renderer/medium/phase/MediumPhaseFunction.d.ts.map +1 -0
  526. package/src/shade/renderer/medium/phase/MediumPhaseFunction.js +42 -0
  527. package/src/shade/renderer/medium/phase/PhaseCornetteShanks.d.ts +23 -0
  528. package/src/shade/renderer/medium/phase/PhaseCornetteShanks.d.ts.map +1 -0
  529. package/src/shade/renderer/medium/phase/PhaseCornetteShanks.js +45 -0
  530. package/src/shade/renderer/medium/phase/PhaseDraine.d.ts +30 -0
  531. package/src/shade/renderer/medium/phase/PhaseDraine.d.ts.map +1 -0
  532. package/src/shade/renderer/medium/phase/PhaseDraine.js +58 -0
  533. package/src/shade/renderer/medium/phase/PhaseFournierForand.d.ts +24 -0
  534. package/src/shade/renderer/medium/phase/PhaseFournierForand.d.ts.map +1 -0
  535. package/src/shade/renderer/medium/phase/PhaseFournierForand.js +53 -0
  536. package/src/shade/renderer/medium/phase/PhaseHenyeyGreenstein.d.ts +21 -0
  537. package/src/shade/renderer/medium/phase/PhaseHenyeyGreenstein.d.ts.map +1 -0
  538. package/src/shade/renderer/medium/phase/PhaseHenyeyGreenstein.js +43 -0
  539. package/src/shade/renderer/medium/phase/PhaseJendersieDeon.d.ts +25 -0
  540. package/src/shade/renderer/medium/phase/PhaseJendersieDeon.d.ts.map +1 -0
  541. package/src/shade/renderer/medium/phase/PhaseJendersieDeon.js +66 -0
  542. package/src/shade/renderer/medium/phase/PhaseRayleigh.d.ts +9 -0
  543. package/src/shade/renderer/medium/phase/PhaseRayleigh.d.ts.map +1 -0
  544. package/src/shade/renderer/medium/phase/PhaseRayleigh.js +21 -0
  545. package/src/shade/renderer/medium/phase/PhaseWaterMolecular.d.ts +28 -0
  546. package/src/shade/renderer/medium/phase/PhaseWaterMolecular.d.ts.map +1 -0
  547. package/src/shade/renderer/medium/phase/PhaseWaterMolecular.js +49 -0
  548. package/src/shade/renderer/medium/water/WATER_DEFAULT_PATH_LENGTHS.d.ts +10 -0
  549. package/src/shade/renderer/medium/water/WATER_DEFAULT_PATH_LENGTHS.d.ts.map +1 -0
  550. package/src/shade/renderer/medium/water/WATER_DEFAULT_PATH_LENGTHS.js +25 -0
  551. package/src/shade/renderer/medium/water/water_iop_from_appearance.d.ts +47 -0
  552. package/src/shade/renderer/medium/water/water_iop_from_appearance.d.ts.map +1 -0
  553. package/src/shade/renderer/medium/water/water_iop_from_appearance.js +174 -0
  554. package/src/shade/renderer/medium/water/water_iop_from_constituents.d.ts +57 -0
  555. package/src/shade/renderer/medium/water/water_iop_from_constituents.d.ts.map +1 -0
  556. package/src/shade/renderer/medium/water/water_iop_from_constituents.js +242 -0
  557. package/src/shade/renderer/medium/water/water_iop_jerlov.d.ts +41 -0
  558. package/src/shade/renderer/medium/water/water_iop_jerlov.d.ts.map +1 -0
  559. package/src/shade/renderer/medium/water/water_iop_jerlov.js +231 -0
  560. package/src/shade/renderer/medium/water/water_iop_spectral_reference.d.ts +66 -0
  561. package/src/shade/renderer/medium/water/water_iop_spectral_reference.d.ts.map +1 -0
  562. package/src/shade/renderer/medium/water/water_iop_spectral_reference.js +223 -0
  563. package/src/shade/renderer/medium/water/water_medium_from_iop.d.ts +96 -0
  564. package/src/shade/renderer/medium/water/water_medium_from_iop.d.ts.map +1 -0
  565. package/src/shade/renderer/medium/water/water_medium_from_iop.js +145 -0
  566. package/src/shade/renderer/medium/water/water_presets.d.ts +69 -0
  567. package/src/shade/renderer/medium/water/water_presets.d.ts.map +1 -0
  568. package/src/shade/renderer/medium/water/water_presets.js +119 -0
  569. package/src/shade/renderer/medium/water/water_rgb_from_spectral.d.ts +69 -0
  570. package/src/shade/renderer/medium/water/water_rgb_from_spectral.d.ts.map +1 -0
  571. package/src/shade/renderer/medium/water/water_rgb_from_spectral.js +341 -0
  572. package/src/shade/renderer/particles/DESIGN.md +4 -2
  573. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_voxel_fade.d.ts +26 -0
  574. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_voxel_fade.d.ts.map +1 -0
  575. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_voxel_fade.js +71 -0
  576. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  577. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +16 -1
  578. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
  579. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +6 -13
  580. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +520 -0
  581. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  582. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -0
  583. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  584. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +2 -0
  585. package/src/shade/renderer/path_tracer/graph_path_trace_scene.d.ts.map +1 -1
  586. package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +188 -185
  587. package/src/shade/renderer/path_tracer/shader/STANDARD_MATERIAL_DATA_STRUCT.d.ts.map +1 -1
  588. package/src/shade/renderer/path_tracer/shader/STANDARD_MATERIAL_DATA_STRUCT.js +4 -1
  589. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts +13 -0
  590. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.d.ts.map +1 -0
  591. package/src/shade/renderer/path_tracer/shader/chunk_indirect_sample_tangent_normal.js +29 -0
  592. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.d.ts +79 -0
  593. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.d.ts.map +1 -1
  594. package/src/shade/renderer/path_tracer/shader/chunk_render_trace_path.js +360 -70
  595. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  596. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +4 -3
  597. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_beam.d.ts +24 -0
  598. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_beam.d.ts.map +1 -0
  599. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_beam.js +99 -0
  600. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_connect.d.ts +68 -0
  601. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_connect.d.ts.map +1 -0
  602. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_connect.js +263 -0
  603. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_constraint.d.ts +55 -0
  604. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_constraint.d.ts.map +1 -0
  605. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_constraint.js +148 -0
  606. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light.d.ts +17 -0
  607. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light.d.ts.map +1 -0
  608. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light.js +41 -0
  609. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light_sample.d.ts +20 -0
  610. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light_sample.d.ts.map +1 -0
  611. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_light_sample.js +105 -0
  612. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle.d.ts +28 -0
  613. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle.d.ts.map +1 -0
  614. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle.js +97 -0
  615. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle_of_hit.d.ts +12 -0
  616. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle_of_hit.d.ts.map +1 -0
  617. package/src/shade/renderer/path_tracer/shader/manifold/chunk_manifold_triangle_of_hit.js +46 -0
  618. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_interface.d.ts +25 -0
  619. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_interface.d.ts.map +1 -0
  620. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_interface.js +75 -0
  621. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_path.d.ts +54 -0
  622. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_path.d.ts.map +1 -0
  623. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_path.js +245 -0
  624. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_phase.d.ts +42 -0
  625. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_phase.d.ts.map +1 -0
  626. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_phase.js +236 -0
  627. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_scatter_nee.d.ts +24 -0
  628. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_scatter_nee.d.ts.map +1 -0
  629. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_scatter_nee.js +97 -0
  630. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_stack.d.ts +57 -0
  631. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_stack.d.ts.map +1 -0
  632. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_stack.js +222 -0
  633. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_transport.d.ts +88 -0
  634. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_transport.d.ts.map +1 -0
  635. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_transport.js +304 -0
  636. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_volumes.d.ts +35 -0
  637. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_volumes.d.ts.map +1 -0
  638. package/src/shade/renderer/path_tracer/shader/media/chunk_medium_volumes.js +137 -0
  639. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  640. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
  641. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +85 -84
  642. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts +8 -0
  643. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.d.ts.map +1 -1
  644. package/src/shade/renderer/rasterize/native/avboit/AVBOITSettings.js +9 -0
  645. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +12 -2
  646. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  647. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +12 -3
  648. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts +13 -7
  649. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.d.ts.map +1 -1
  650. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_CONSTANTS.js +13 -7
  651. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +309 -0
  652. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +54 -9
  653. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.d.ts.map +1 -1
  654. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +9 -1
  655. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_footprint_bias.d.ts +33 -0
  656. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_footprint_bias.d.ts.map +1 -0
  657. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_footprint_bias.js +45 -0
  658. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts +4 -0
  659. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.d.ts.map +1 -1
  660. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_integral_depth_coordinate.js +6 -2
  661. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts +2 -1
  662. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.d.ts.map +1 -1
  663. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_sample_transmittance.js +4 -2
  664. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_level_word.d.ts +14 -0
  665. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_level_word.d.ts.map +1 -0
  666. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_level_word.js +28 -0
  667. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_lut_entry.d.ts +10 -0
  668. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_lut_entry.d.ts.map +1 -0
  669. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_lut_entry.js +18 -0
  670. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_marks.d.ts +19 -0
  671. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_marks.d.ts.map +1 -0
  672. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_marks.js +44 -0
  673. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_step_count.d.ts +10 -0
  674. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_step_count.d.ts.map +1 -0
  675. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_warp_step_count.js +17 -0
  676. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  677. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -1
  678. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.d.ts.map +1 -1
  679. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_build_warp.js +163 -64
  680. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  681. package/src/shade/renderer/scene/GPUSceneContext.js +4 -1
  682. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.d.ts.map +1 -1
  683. package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +5 -0
  684. package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts +12 -1
  685. package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.d.ts.map +1 -1
  686. package/src/shade/renderer/shader/chunk/atmosphere/C_MIE_SCATTERING_DECLARATION.js +22 -3
  687. package/src/shade/renderer/shader/chunk/atmosphere/phase/chunk_sample_henyey_greenstein_cos.d.ts +18 -0
  688. package/src/shade/renderer/shader/chunk/atmosphere/phase/chunk_sample_henyey_greenstein_cos.d.ts.map +1 -0
  689. package/src/shade/renderer/shader/chunk/atmosphere/phase/chunk_sample_henyey_greenstein_cos.js +31 -0
  690. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_phase_fournier_forand.d.ts +43 -0
  691. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_phase_fournier_forand.d.ts.map +1 -0
  692. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_phase_fournier_forand.js +153 -0
  693. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_sample_fournier_forand.d.ts +13 -0
  694. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_sample_fournier_forand.d.ts.map +1 -0
  695. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/chunk_sample_fournier_forand.js +57 -0
  696. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/fournier_forand_parameters_from_backscatter.d.ts +45 -0
  697. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/fournier_forand_parameters_from_backscatter.d.ts.map +1 -0
  698. package/src/shade/renderer/shader/chunk/atmosphere/phase/ff/fournier_forand_parameters_from_backscatter.js +109 -0
  699. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_phase_draine.d.ts.map +1 -1
  700. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_phase_draine.js +6 -3
  701. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine.d.ts +24 -0
  702. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine.d.ts.map +1 -0
  703. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine.js +49 -0
  704. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine_cos.d.ts +18 -0
  705. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine_cos.d.ts.map +1 -1
  706. package/src/shade/renderer/shader/chunk/atmosphere/phase/jd/chunk_sample_draine_cos.js +18 -0
  707. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts +3 -0
  708. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.d.ts.map +1 -1
  709. package/src/shade/renderer/shader/chunk/brdf/dfg/chunk_integrate_brdf.js +3 -0
  710. package/src/shade/renderer/shader/chunk/brdf/dfg/shader_split_sum_dgf_lut.d.ts.map +1 -1
  711. package/src/shade/renderer/shader/chunk/brdf/dfg/shader_split_sum_dgf_lut.js +3 -1
  712. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_dielectric.d.ts +24 -0
  713. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_dielectric.d.ts.map +1 -0
  714. package/src/shade/renderer/shader/chunk/brdf/fresnel/chunk_F_dielectric.js +53 -0
  715. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_scene_point_query_is_inside_geometry.d.ts +7 -1
  716. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_scene_point_query_is_inside_geometry.d.ts.map +1 -1
  717. package/src/shade/renderer/shader/chunk/geometry/ray/chunk_scene_point_query_is_inside_geometry.js +12 -60
  718. package/src/shade/renderer/shader/chunk/geometry/sphere/chunk_compute_spherical_excess.d.ts +26 -6
  719. package/src/shade/renderer/shader/chunk/geometry/sphere/chunk_compute_spherical_excess.d.ts.map +1 -1
  720. package/src/shade/renderer/shader/chunk/geometry/sphere/chunk_compute_spherical_excess.js +30 -20
  721. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_directional.d.ts.map +1 -1
  722. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_directional.js +3 -1
  723. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_point.d.ts.map +1 -1
  724. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_point.js +3 -1
  725. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_spot.d.ts.map +1 -1
  726. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_importance_spot.js +3 -1
  727. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_receiver_cosine.d.ts +14 -0
  728. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_receiver_cosine.d.ts.map +1 -0
  729. package/src/shade/renderer/shader/chunk/light/sample/chunk_light_receiver_cosine.js +25 -0
  730. package/src/shade/renderer/shader/chunk/light/sample/chunk_select_light_importance.d.ts +9 -2
  731. package/src/shade/renderer/shader/chunk/light/sample/chunk_select_light_importance.d.ts.map +1 -1
  732. package/src/shade/renderer/shader/chunk/light/sample/chunk_select_light_importance.js +33 -10
  733. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_newton_ray.d.ts.map +1 -1
  734. package/src/shade/renderer/shader/chunk/screen_space/chunk_screen_space_newton_ray.js +71 -37
  735. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_band_of_index.d.ts +14 -0
  736. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_band_of_index.d.ts.map +1 -0
  737. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_band_of_index.js +30 -0
  738. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_basis_function.d.ts +19 -0
  739. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_basis_function.d.ts.map +1 -0
  740. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_basis_function.js +73 -0
  741. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_vmf_window.d.ts +19 -0
  742. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_vmf_window.d.ts.map +1 -0
  743. package/src/shade/renderer/shader/chunk/spherical_harmonics/chunk_sh_vmf_window.js +25 -0
  744. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/SH_EXP_P4Q2_PROBE_STRUCT.d.ts +17 -0
  745. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/SH_EXP_P4Q2_PROBE_STRUCT.d.ts.map +1 -0
  746. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/SH_EXP_P4Q2_PROBE_STRUCT.js +23 -0
  747. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_p4q2_base_reflectance.d.ts +26 -0
  748. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_p4q2_base_reflectance.d.ts.map +1 -0
  749. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_p4q2_base_reflectance.js +55 -0
  750. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts +52 -0
  751. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.d.ts.map +1 -0
  752. package/src/shade/renderer/shader/chunk/spherical_harmonics/exponential/chunk_sh_exp_split_sum.js +65 -0
  753. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_basis_at.d.ts +13 -0
  754. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_basis_at.d.ts.map +1 -0
  755. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_basis_at.js +229 -0
  756. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_color_evaluate_vmf.d.ts +23 -0
  757. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_color_evaluate_vmf.d.ts.map +1 -0
  758. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh10_color_evaluate_vmf.js +278 -0
  759. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh2_color_evaluate_vmf.d.ts +23 -0
  760. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh2_color_evaluate_vmf.d.ts.map +1 -0
  761. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh2_color_evaluate_vmf.js +58 -0
  762. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh3_color_evaluate_vmf.d.ts +23 -0
  763. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh3_color_evaluate_vmf.d.ts.map +1 -0
  764. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh3_color_evaluate_vmf.js +75 -0
  765. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_basis_at.d.ts +13 -0
  766. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_basis_at.d.ts.map +1 -0
  767. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_basis_at.js +70 -0
  768. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_color_evaluate_vmf.d.ts +23 -0
  769. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_color_evaluate_vmf.d.ts.map +1 -0
  770. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh4_color_evaluate_vmf.js +95 -0
  771. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_basis_at.d.ts +13 -0
  772. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_basis_at.d.ts.map +1 -0
  773. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_basis_at.js +89 -0
  774. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_color_evaluate_vmf.d.ts +23 -0
  775. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_color_evaluate_vmf.d.ts.map +1 -0
  776. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh5_color_evaluate_vmf.js +118 -0
  777. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_basis_at.d.ts +13 -0
  778. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_basis_at.d.ts.map +1 -0
  779. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_basis_at.js +111 -0
  780. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_color_evaluate_vmf.d.ts +23 -0
  781. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_color_evaluate_vmf.d.ts.map +1 -0
  782. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh6_color_evaluate_vmf.js +144 -0
  783. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_basis_at.d.ts +13 -0
  784. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_basis_at.d.ts.map +1 -0
  785. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_basis_at.js +136 -0
  786. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_color_evaluate_vmf.d.ts +23 -0
  787. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_color_evaluate_vmf.d.ts.map +1 -0
  788. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh7_color_evaluate_vmf.js +173 -0
  789. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_basis_at.d.ts +13 -0
  790. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_basis_at.d.ts.map +1 -0
  791. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_basis_at.js +164 -0
  792. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_color_evaluate_vmf.d.ts +23 -0
  793. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_color_evaluate_vmf.d.ts.map +1 -0
  794. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh8_color_evaluate_vmf.js +205 -0
  795. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_basis_at.d.ts +13 -0
  796. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_basis_at.d.ts.map +1 -0
  797. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_basis_at.js +195 -0
  798. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_color_evaluate_vmf.d.ts +23 -0
  799. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_color_evaluate_vmf.d.ts.map +1 -0
  800. package/src/shade/renderer/shader/chunk/spherical_harmonics/generated/chunk_sh9_color_evaluate_vmf.js +240 -0
  801. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts +0 -6
  802. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.d.ts.map +1 -1
  803. package/src/shade/renderer/shader/resource/ShaderResourceGroupDescriptor.js +46 -1
  804. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +7 -7
  805. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +7 -7
  806. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +42 -10
  807. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
  808. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +104 -48
  809. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +20 -4
  810. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  811. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +186 -74
  812. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +2 -1
  813. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  814. package/src/shade/renderer/shadow/map/Shadowmap.js +2 -1
  815. package/src/shade/renderer/shadow/map/csm/CSM_CASCADE_STRUCT.d.ts +30 -0
  816. package/src/shade/renderer/shadow/map/csm/CSM_CASCADE_STRUCT.d.ts.map +1 -0
  817. package/src/shade/renderer/shadow/map/csm/CSM_CASCADE_STRUCT.js +52 -0
  818. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts +14 -0
  819. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.d.ts.map +1 -0
  820. package/src/shade/renderer/shadow/map/csm/CSM_SHADOWMAP_STRUCT.js +20 -0
  821. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_DEFAULT_CASCADE_COUNT.d.ts +8 -0
  822. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_DEFAULT_CASCADE_COUNT.d.ts.map +1 -0
  823. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_DEFAULT_CASCADE_COUNT.js +7 -0
  824. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts +8 -6
  825. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts.map +1 -1
  826. package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +28 -34
  827. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_csm_compute_cascade_blended.d.ts +3 -2
  828. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_csm_compute_cascade_blended.d.ts.map +1 -1
  829. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_csm_compute_cascade_blended.js +19 -14
  830. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts +4 -3
  831. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.d.ts.map +1 -1
  832. package/src/shade/renderer/shadow/map/shader/chunk_shadowmap_sample_directional.js +12 -7
  833. package/src/shade/renderer/shadow/map/shadowmap_budget_carry_over.d.ts +4 -4
  834. package/src/shade/renderer/shadow/map/shadowmap_budget_carry_over.js +4 -4
  835. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.d.ts.map +1 -1
  836. package/src/shade/renderer/shadow/vsm/GPUViewShadowMaps.js +39 -17
  837. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.d.ts.map +1 -1
  838. package/src/shade/renderer/shadow/vsm/GPUVirtualShadowTextureResidence.js +5 -36
  839. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.d.ts.map +1 -1
  840. package/src/shade/renderer/shadow/vsm/VSM_UNIFORMS_STRUCT.js +3 -2
  841. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts +1 -1
  842. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.d.ts.map +1 -1
  843. package/src/shade/renderer/shadow/vsm/VirtualShadowMap.js +49 -35
  844. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts +4 -1
  845. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.d.ts.map +1 -1
  846. package/src/shade/renderer/shadow/vsm/VirtualShadowmapRenderer.js +8 -9
  847. package/src/shade/renderer/shadow/vsm/debug_inspect_residence_buffer.js +2 -2
  848. package/src/shade/renderer/shadow/vsm/decode_tile_address.d.ts.map +1 -1
  849. package/src/shade/renderer/shadow/vsm/decode_tile_address.js +15 -23
  850. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.d.ts.map +1 -1
  851. package/src/shade/renderer/shadow/vsm/vms_pipeline_compute_coarse_bounds.js +6 -9
  852. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.d.ts.map +1 -1
  853. package/src/shade/renderer/shadow/vsm/vsm_residence_pipeline.js +19 -9
  854. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.d.ts.map +1 -1
  855. package/src/shade/renderer/shadow/vsm/vsm_tile_allocation_pipeline.js +18 -6
  856. package/src/shade/renderer/texture/util/BLACK_PIXEL_TEXTURE.d.ts +1 -1
  857. package/src/shade/renderer/texture/util/BLACK_PIXEL_TEXTURE.d.ts.map +1 -1
  858. package/src/shade/renderer/texture/util/PIXEL_TEXTURE_NORMAL.d.ts +18 -1
  859. package/src/shade/renderer/texture/util/PIXEL_TEXTURE_NORMAL.d.ts.map +1 -1
  860. package/src/shade/renderer/texture/util/PIXEL_TEXTURE_NORMAL.js +24 -3
  861. package/src/shade/renderer/texture/util/WHITE_PIXEL_TEXTURE.d.ts +1 -1
  862. package/src/shade/renderer/texture/util/WHITE_PIXEL_TEXTURE.d.ts.map +1 -1
  863. package/src/shade/renderer/texture/util/get_single_pixel_texture.d.ts +0 -1
  864. package/src/shade/renderer/texture/util/get_single_pixel_texture.d.ts.map +1 -1
  865. package/src/shade/renderer/texture/util/get_single_pixel_texture.js +2 -23
  866. package/src/shade/renderer/texture/util/single_pixel_texture_from_sampler.d.ts +11 -0
  867. package/src/shade/renderer/texture/util/single_pixel_texture_from_sampler.d.ts.map +1 -0
  868. package/src/shade/renderer/texture/util/single_pixel_texture_from_sampler.js +34 -0
  869. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts +17 -8
  870. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.d.ts.map +1 -1
  871. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +35 -64
  872. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts +21 -0
  873. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.d.ts.map +1 -0
  874. package/src/shade/renderer/volumetrics/chunk_participating_media_volume_sample.js +70 -0
  875. package/src/shade/renderer/volumetrics/chunk_participating_media_volumes_iterate.d.ts +31 -0
  876. package/src/shade/renderer/volumetrics/chunk_participating_media_volumes_iterate.d.ts.map +1 -0
  877. package/src/shade/renderer/volumetrics/chunk_participating_media_volumes_iterate.js +86 -0
  878. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  879. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -4
  880. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.d.ts.map +1 -1
  881. package/src/shade/renderer/volumetrics/shader_volumetrics_build_participating_media.js +6 -7
  882. package/src/shade/renderer/volumetrics/shader_volumetrics_build_scattering_lut.js +7 -7
  883. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +13 -1
  884. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  885. package/src/shade/renderer/water/GPUWaterRenderer.js +74 -25
  886. package/src/shade/renderer/water/chunk_water_gi.d.ts +14 -0
  887. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -0
  888. package/src/shade/renderer/water/chunk_water_gi.js +56 -0
  889. package/src/shade/renderer/water/chunk_water_transport.d.ts +2 -0
  890. package/src/shade/renderer/water/chunk_water_transport.d.ts.map +1 -1
  891. package/src/shade/renderer/water/chunk_water_transport.js +51 -40
  892. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +29 -0
  893. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -0
  894. package/src/shade/renderer/water/medium/GPUWaterBodies.js +116 -0
  895. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts +23 -0
  896. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.d.ts.map +1 -0
  897. package/src/shade/renderer/water/medium/WATER_BODIES_STRUCT.js +42 -0
  898. package/src/shade/renderer/water/medium/chunk_water_medium_derived.d.ts +9 -0
  899. package/src/shade/renderer/water/medium/chunk_water_medium_derived.d.ts.map +1 -0
  900. package/src/shade/renderer/water/medium/chunk_water_medium_derived.js +55 -0
  901. package/src/shade/renderer/water/medium/chunk_water_medium_scattering.d.ts +8 -0
  902. package/src/shade/renderer/water/medium/chunk_water_medium_scattering.d.ts.map +1 -0
  903. package/src/shade/renderer/water/medium/chunk_water_medium_scattering.js +17 -0
  904. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +8 -0
  905. package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +1 -0
  906. package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +30 -0
  907. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts +28 -0
  908. package/src/shade/renderer/water/optics/chunk_water_inscatter.d.ts.map +1 -0
  909. package/src/shade/renderer/water/optics/chunk_water_inscatter.js +123 -0
  910. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts +23 -0
  911. package/src/shade/renderer/water/optics/chunk_water_light_transmittance.d.ts.map +1 -0
  912. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts +18 -0
  913. package/src/shade/renderer/water/optics/chunk_water_light_transmittance_dry.d.ts.map +1 -0
  914. package/src/shade/renderer/water/optics/chunk_water_optics.d.ts +12 -0
  915. package/src/shade/renderer/water/optics/chunk_water_optics.d.ts.map +1 -0
  916. package/src/shade/renderer/water/optics/chunk_water_optics.js +75 -0
  917. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts +27 -0
  918. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.d.ts.map +1 -0
  919. package/src/shade/renderer/water/optics/chunk_water_receiver_downwelling.js +74 -0
  920. package/src/shade/renderer/water/shader_water.d.ts +10 -4
  921. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  922. package/src/shade/renderer/water/shader_water.js +406 -384
  923. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  924. package/src/shade/renderer/water/shader_water_avboit.js +19 -9
  925. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +98 -0
  926. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +1 -0
  927. package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +408 -0
  928. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts +12 -0
  929. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.d.ts.map +1 -0
  930. package/src/shade/renderer/water/surface/WATER_SURFACE_VERTEX_STRUCT.js +27 -0
  931. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts +14 -0
  932. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.d.ts.map +1 -0
  933. package/src/shade/renderer/water/surface/WATER_WAVE_PARAMETERS_STRUCT.js +49 -0
  934. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +15 -0
  935. package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +1 -0
  936. package/src/shade/renderer/water/surface/chunk_water_wave.js +48 -0
  937. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts +9 -0
  938. package/src/shade/renderer/water/surface/chunk_water_wave_grid.d.ts.map +1 -0
  939. package/src/shade/renderer/water/surface/chunk_water_wave_grid.js +47 -0
  940. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts +10 -0
  941. package/src/shade/renderer/water/surface/shader_water_surface_write.d.ts.map +1 -0
  942. package/src/shade/renderer/water/surface/shader_water_surface_write.js +51 -0
  943. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts +12 -0
  944. package/src/shade/renderer/water/surface/shader_water_wave_step.d.ts.map +1 -0
  945. package/src/shade/renderer/water/surface/shader_water_wave_step.js +54 -0
  946. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts +13 -0
  947. package/src/shade/renderer/water/surface/water_surface_grid_indices.d.ts.map +1 -0
  948. package/src/shade/renderer/water/surface/water_surface_grid_indices.js +39 -0
  949. package/src/shade/renderer/water/water_missing_receiver_path.d.ts +17 -0
  950. package/src/shade/renderer/water/water_missing_receiver_path.d.ts.map +1 -0
  951. package/src/shade/renderer/water/water_missing_receiver_path.js +40 -0
  952. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  953. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +247 -23
  954. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts +18 -14
  955. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  956. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +48 -6
  957. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts +0 -29
  958. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts.map +0 -1
  959. package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.js +0 -43
  960. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASCADE_COUNT.d.ts +0 -7
  961. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASCADE_COUNT.d.ts.map +0 -1
  962. package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASCADE_COUNT.js +0 -6
@@ -4,8 +4,11 @@ import { combine_friction, combine_restitution } from "../contact/combine_materi
4
4
  import { BodyKind } from "../ecs/BodyKind.js";
5
5
  import { is_sensor } from "../ecs/is_sensor.js";
6
6
  import { RigidBodyFlags } from "../ecs/RigidBodyFlags.js";
7
+ import { SleepState } from "../ecs/SleepState.js";
8
+ import { angular_effective_mass_raw, world_inverse_inertia_apply_raw } from "../inertia/world_inverse_inertia.js";
7
9
  import { PhysicsSurfacePoint } from "../queries/PhysicsSurfacePoint.js";
8
- import { shape_cast } from "../queries/shape_cast.js";
10
+ import { shape_cast, shape_cast_struck_support } from "../queries/shape_cast.js";
11
+ import { PENETRATION_SLOP } from "../solver/solve_contacts.js";
9
12
 
10
13
  /**
11
14
  * Continuous collision detection — linear shape-cast.
@@ -21,11 +24,19 @@ import { shape_cast } from "../queries/shape_cast.js";
21
24
  * the substep solver has produced each body's final pose, sweep a CCD-flagged
22
25
  * fast mover's primary collider along its NET step translation
23
26
  * (start-of-step → final pose) using the existing {@link shape_cast} TOI engine.
24
- * On the first blocker, clamp the body to the contact pose, remove the inbound
25
- * normal component of its velocity (an inelastic stop), and RECORD the impact
26
- * on the pair's manifold ({@link record_ccd_contact}) so this step's event diff
27
- * reports it — the next discrete step then resolves the now-touching contact
28
- * with the real material / restitution.
27
+ * On the first blocker, clamp the body to the contact pose, RESPOND to the
28
+ * impact there and then ({@link ccd_respond}: the pair's restitution, and an
29
+ * impulse shared with a dynamic blocker), and RECORD the impact on the pair's
30
+ * manifold ({@link record_ccd_contact}) so this step's event diff reports it.
31
+ *
32
+ * The response cannot be left to the next discrete step. The clamp leaves the
33
+ * body clear of what it struck — {@link shape_cast} parks it 1e-5 to 1.25e-5 m
34
+ * short of a convex blocker, and on a triangle's face to within 5e-16 m either
35
+ * side — and the narrowphase reports only strictly positive penetration, so
36
+ * the next step sees no contact to respond with — and restitution arms only on
37
+ * an approach faster than `PhysicsSystem.restitutionThreshold`, which a stopped
38
+ * body no longer has. The sweep is the only part of the pipeline that saw the
39
+ * impact, so it is the part that answers it.
29
40
  *
30
41
  * Scope (v1, deliberate):
31
42
  * - LINEAR sweep only: the orientation is held fixed through the sweep (the
@@ -37,8 +48,11 @@ import { shape_cast } from "../queries/shape_cast.js";
37
48
  * leaves); APPROXIMATE against other dynamic bodies (they have moved this
38
49
  * step too, but the sweep sees their start-of-step broadphase AABBs) — the
39
50
  * speculative-margin floor for the dynamic-vs-dynamic case.
40
- * - The CCD stop itself is inelastic; the impact does not bounce. Restitution
41
- * applies on the next discrete contact.
51
+ * - One impact per body per step, answered by one normal impulse and one
52
+ * Coulomb friction impulse ({@link ccd_friction}) at the contact point. The
53
+ * normal impulse against an immovable blocker is linear only (see
54
+ * {@link ccd_respond}); friction turns the body as well, which is how a
55
+ * ball spinning into a wall comes off it rolling.
42
56
  */
43
57
 
44
58
  /**
@@ -59,6 +73,39 @@ import { shape_cast } from "../queries/shape_cast.js";
59
73
  */
60
74
  export const CCD_MIN_SWEEP_DISTANCE = 1e-3;
61
75
 
76
+ /**
77
+ * How far past the contact pose, along the contact normal, a body that STARTED
78
+ * its step touching what the sweep struck (within
79
+ * {@link CCD_MIN_SWEEP_DISTANCE} of it) may end the step and be left where the
80
+ * step put it: the solver's {@link PENETRATION_SLOP}. Such a body is resting
81
+ * on or sliding along the surface, and overlaps it at the end by no more than
82
+ * the solver lets a resting contact sink, so the next discrete step resolves
83
+ * it like any contact, with friction. A body whose centre would end on the
84
+ * surface's far side is clamped all the same: one thinner than the slop
85
+ * crosses a mesh triangle whole within it.
86
+ *
87
+ * It is that one COLLIDER the body is left to the discrete step for, not its
88
+ * whole sweep: the sweep steps past it ({@link step_past_slid_along}) and goes
89
+ * on to whatever else is in the path, as Box3D's continuous pass rejects a
90
+ * hit at a time of impact of zero shape by shape and continues its query.
91
+ * Skipping the whole sweep instead let a ball sliding on a floor it touched
92
+ * through a 1 cm or 2 mm wall in 8 of 48 cases, a 60 m/s one ending 30 m on.
93
+ *
94
+ * Clamping a body that started the step touching the surface put it back
95
+ * where it started, because the sweep found the contact at the start. Exactly
96
+ * touching, it then had no discrete contact either, so the next step did the
97
+ * same. A ball landing on a μ 0.5 floor while moving at 5 to 42 m/s stood
98
+ * still for 43 of its first 60 steps with its speed untouched, and a missile
99
+ * stopped at a box's corner stood there for good with the metre a second the
100
+ * corner's normal left it.
101
+ *
102
+ * Only a body that starts touching. Leaving every end pose this shallow to the
103
+ * discrete step also took over slow bounces from the sweep's exact response:
104
+ * bounces at 240 Hz lost up to 20% of their energy.
105
+ * @type {number}
106
+ */
107
+ const CCD_CONTACT_SLOP = PENETRATION_SLOP;
108
+
62
109
  // ── Module scratch ──────────────────────────────────────────────────────────
63
110
  // CCD runs inside the step loop; reuse buffers so the pass allocates nothing.
64
111
 
@@ -79,6 +126,13 @@ const _ray = {
79
126
  /** Sweep result reused across bodies inside {@link ccd_resolve}. */
80
127
  const _hit = new PhysicsSurfacePoint();
81
128
 
129
+ /**
130
+ * The swept body's orientation as the array {@link ccd_sweep_segment} takes, copied out of its
131
+ * transform once per body inside {@link ccd_resolve}: reading a Transform64's `rotation` builds a
132
+ * fresh view on every read. The sweep only translates, so it holds for every re-sweep of that body.
133
+ */
134
+ const _sweep_rotation = new Float64Array(4);
135
+
82
136
  /**
83
137
  * The swept shape held at its CLAMPED pose, for the contact-witness support
84
138
  * query in {@link record_ccd_contact}.
@@ -86,9 +140,63 @@ const _hit = new PhysicsSurfacePoint();
86
140
  */
87
141
  const _clamped = new PosedShape3D();
88
142
 
89
- /** Contact witness written by {@link _clamped}'s support query. */
143
+ /**
144
+ * The impact's contact point, written by {@link ccd_contact}: the centre of the
145
+ * swept shape's own surface feature facing the blocker at the clamped pose.
146
+ */
90
147
  const _witness = new Float64Array(3);
91
148
 
149
+ /**
150
+ * The direction each witness support is asked along.
151
+ */
152
+ const _witness_direction = new Float64Array(3);
153
+
154
+ /**
155
+ * How many supports {@link ccd_contact} averages for the contact point, the
156
+ * tilt of their directions off the contact normal, and the phase of the first
157
+ * one. Eight directions 45° apart give each corner of a facing box face two
158
+ * of them, and each end of a facing edge four; the phase keeps the set off the
159
+ * axis-aligned directions, where two of a face's corners would tie. The tilt
160
+ * is the flatness a facing feature is allowed: corners within ~1% of its
161
+ * extent of the plane closest to the blocker count as touching it.
162
+ * @type {number}
163
+ */
164
+ const WITNESS_SAMPLES = 8;
165
+ const WITNESS_TILT = 0.01;
166
+ const WITNESS_PHASE = 0.3;
167
+
168
+ /**
169
+ * How spread across their thinnest direction, against their widest, the
170
+ * struck feature's samples must be to span an AREA — a triangle met on its
171
+ * face, rather than on an edge (two points) or a vertex (one), whose spread
172
+ * across is nothing but rounding.
173
+ * @type {number}
174
+ */
175
+ const FACE_SPREAD = 1e-6;
176
+
177
+ /** The pair's combined friction and restitution, written by {@link ccd_contact}. */
178
+ let _friction = 0;
179
+ let _restitution = 0;
180
+
181
+ /**
182
+ * How far the clamped body's stored velocity lags its actual motion along the
183
+ * contact normal at the impact, relative to the blocker's (a falling blocker
184
+ * lags as much as the body), written by {@link ccd_velocity_at_impact}.
185
+ * @type {number}
186
+ */
187
+ let _impact_lag = 0;
188
+
189
+ /**
190
+ * The impulse {@link ccd_respond} applies, and scratch for its effective mass:
191
+ * a `LockRot*`-masked inverse-inertia diagonal and a world-space product.
192
+ */
193
+ const _impulse = new Float64Array(3);
194
+ const _masked_inertia = new Float64Array(3);
195
+ const _inertia_scratch = new Float64Array(3);
196
+
197
+ /** A collider's local bounding box, for {@link body_extent}. */
198
+ const _local_box = new Float64Array(6);
199
+
92
200
  /**
93
201
  * Slots {@link record_ccd_contact} wrote this step, as `(slot, idA, idB)`
94
202
  * triples, for {@link ccd_release_contacts} to take back out again. Grows by
@@ -100,6 +208,14 @@ let _written = new Uint32Array(3 * 16);
100
208
  /** Number of triples currently in {@link _written}. */
101
209
  let _written_count = 0;
102
210
 
211
+ /**
212
+ * Storage indices of the bodies the current pass clamped, in the order it
213
+ * clamped them; {@link ccd_resolve} returns how many. Grows by doubling;
214
+ * module-scoped so the pass allocates nothing in steady state.
215
+ * @type {Uint32Array}
216
+ */
217
+ let _clamped_bodies = new Uint32Array(16);
218
+
103
219
  /**
104
220
  * CCD-eligible body indices of the current pass, ordered by ENTITY id.
105
221
  * Grows by doubling; module-scoped so the pass allocates nothing in steady
@@ -122,6 +238,25 @@ let _system = null;
122
238
  */
123
239
  let _self_body_id = -1;
124
240
 
241
+ /**
242
+ * How many convex colliders one body's sweep may step past as surfaces it is
243
+ * sliding along ({@link CCD_CONTACT_SLOP}) before it is clamped at the next
244
+ * one anyway: a floor, a wall it runs along, and the like, each its own
245
+ * collider.
246
+ * @type {number}
247
+ */
248
+ const CCD_MAX_SLID_ALONG = 4;
249
+
250
+ /**
251
+ * Colliders the current body's sweep steps past, the first
252
+ * {@link _slid_along_count} of them; {@link _ccd_filter} rejects them.
253
+ * @type {Array<Collider|null>}
254
+ */
255
+ const _slid_along = new Array(CCD_MAX_SLID_ALONG).fill(null);
256
+
257
+ /** Number of live entries in {@link _slid_along}. */
258
+ let _slid_along_count = 0;
259
+
125
260
  /**
126
261
  * Sweep filter, mirroring the discrete pipeline's pair acceptance:
127
262
  * - never the swept body itself. BODY-id exclusion: every collider of a
@@ -138,7 +273,9 @@ let _self_body_id = -1;
138
273
  * asking in sweep order let a filter accept for CCD what the broadphase
139
274
  * had rejected. The sweep then clamped the body onto geometry the discrete
140
275
  * pipeline had no pair for — and, once the sweep began reporting its own
141
- * impacts ({@link record_ccd_contact}), raised contact events for it.
276
+ * impacts ({@link record_ccd_contact}), raised contact events for it;
277
+ * - not a collider the body is sliding along ({@link _slid_along}): that
278
+ * contact is the discrete step's, and the sweep goes on past it.
142
279
  *
143
280
  * @param {number} entity candidate body's entity
144
281
  * @param {Collider} collider candidate body's primary collider
@@ -147,6 +284,9 @@ let _self_body_id = -1;
147
284
  */
148
285
  function _ccd_filter(entity, collider, body_id) {
149
286
  if (body_id === _self_body_id) return false;
287
+ for (let i = 0; i < _slid_along_count; i++) {
288
+ if (_slid_along[i] === collider) return false;
289
+ }
150
290
  if (is_sensor(_system.__bodies[body_id_index(body_id)], collider)) return false;
151
291
  if (_self_body_id !== -1) {
152
292
  const self_entity = _system.storage.entity_at(body_id_index(_self_body_id));
@@ -222,25 +362,838 @@ export function ccd_sweep_segment(
222
362
  }
223
363
 
224
364
  // result.t is the impact distance along the unit direction; normalise to a
225
- // segment fraction. shape_cast reports the just-SEPARATING side of its
226
- // bisection, so the swept shape at `result.t` is provably not overlapping —
227
- // safe to place the body there.
365
+ // segment fraction. The swept shape at `result.t` is clear of the blocker
366
+ // or touching it, never in it by more than rounding: a convex blocker's
367
+ // conservative advancement parks it 1e-5 m short, and a triangle face's
368
+ // closed-form time leaves it ON the face — within 5e-16 m of it, on either
369
+ // side, measured over mesh and heightmap floors.
228
370
  const frac = result.t * inv;
229
371
  return frac < 1 ? frac : 1;
230
372
  }
231
373
 
374
+ /**
375
+ * Take the gravity of the part of the step a clamped body did not travel back
376
+ * out of `lv`, its end-of-step linear velocity; and record in
377
+ * {@link _impact_lag} how far the stored velocity lags the body's actual
378
+ * motion along the contact normal.
379
+ *
380
+ * The clamp puts the body back where it struck, part-way through the step, but
381
+ * the velocity it carries out of the solver is the END-of-step one: it has had
382
+ * the whole step's gravity while the body only travelled the part of the step
383
+ * before the impact. Reflected, that velocity hands the bounce the rest of the
384
+ * step's gravity as free energy — an e = 1 ball dropped from 2 m came back to
385
+ * 2.059 m, every bounce, and from 0.5 m to 0.538 m.
386
+ *
387
+ * Gravity is the only thing taken back: `v ← v − g·(dt − τ)`, `τ` the time of
388
+ * impact and `g` the body's own gravity (`gravityScale` applied), as Box3D
389
+ * does. The body is then where its own free flight had it at `τ`, in pose and
390
+ * in velocity, and its free-flight energy is what it was. Gravity acts on the
391
+ * body alone, so taking the lost time's share back from the body alone is
392
+ * exact. ALL of it: taken out along the normal only, a ball falling into a
393
+ * vertical wall kept the vertical gravity of the time it did not fall
394
+ * through, and the integrator's free-flight energy rose by 0.11% to 0.35% a
395
+ * strike (and fell as much for a rising ball). And its OWN gravity, whatever
396
+ * it struck: what a falling blocker did enters the impulse, not the rewind
397
+ * (see {@link blocker_fall}). Taking back
398
+ * the step's WHOLE velocity change, `v_end − v_start`, also took back what the
399
+ * step's contacts had done — from this body only, never from the body on the
400
+ * other side of the contact, and never from its spin. In zero gravity a ball
401
+ * glancing off a free box changed the pair's momentum by up to 15% of itself,
402
+ * and a cloud of CCD bodies drifted by up to 4.7% of its bodies' summed |m·v|;
403
+ * a ball rolling along a wall it was pressed into had the floor's friction
404
+ * taken out of its velocity every step but left in its spin, and reached 1.38
405
+ * times the energy it started with.
406
+ *
407
+ * Under gravity the integrator's substeps (`h` long; velocity first, then
408
+ * position) put the body on the parabola whose velocity is the STORED velocity
409
+ * plus `½·g·h` — the stored one is the average over the substep just taken,
410
+ * half a substep behind the motion. Along the normal the body covered
411
+ * `d_n = (contact pose − start pose)·n` before it struck, starting with the
412
+ * normal motion `w0_n = v_n − g_n·dt + ½·g_n·h`; that fixes its normal motion
413
+ * at impact through `w_n² = w0_n² + 2·g_n·d_n` — the energy relation, so the
414
+ * impact neither gains nor loses — and the time of impact through
415
+ * `d_n = ½·(w0_n + w_n)·τ`.
416
+ *
417
+ * The response works on the normal MOTION of the body relative to the
418
+ * blocker's, which {@link _impact_lag} records: the body's lag `½·g_n·h`, less
419
+ * the blocker's own, `½·f_n·h` for a blocker falling at `f_n`
420
+ * ({@link blocker_fall}). Both lags differ from what the stored velocities
421
+ * say, and an elastic impulse that reverses the relative motion keeps the
422
+ * pair's free-flight energy, each body's on its own trajectory.
423
+ *
424
+ * The rest of the step, `dt − τ`, is lost: the body ends the step at the impact
425
+ * pose with the velocity it had there, which is what Box3D does too (its
426
+ * continuous solver takes the lost time's gravity back out of the velocity).
427
+ * Losing that time costs no energy; spending the lost time's gravity on a body
428
+ * that did not move would.
429
+ *
430
+ * @param {Float64Array} lv the body's linear velocity, rewritten in place
431
+ * @param {number} gx the body's gravity, `gravityScale` applied
432
+ * @param {number} gy
433
+ * @param {number} gz
434
+ * @param {number} fn the blocker's fall along `n` ({@link blocker_fall}), for
435
+ * the relative lag
436
+ * @param {number} cx displacement from the start-of-step pose to the contact pose
437
+ * @param {number} cy
438
+ * @param {number} cz
439
+ * @param {ArrayLike<number>} n the blocker's unit outward normal, toward the body
440
+ * @param {number} frac the sweep's fraction of the step at impact — the time
441
+ * of impact where the normal motion cannot say (it never closed on the blocker)
442
+ * @param {number} dt the step's length
443
+ * @param {number} h the integrator's substep length
444
+ */
445
+ function ccd_velocity_at_impact(lv, gx, gy, gz, fn, cx, cy, cz, n, frac, dt, h) {
446
+ _impact_lag = 0;
447
+ if (!(dt > 0)) return;
448
+
449
+ const nx = n[0], ny = n[1], nz = n[2];
450
+ const gn = gx * nx + gy * ny + gz * nz;
451
+ const dn = cx * nx + cy * ny + cz * nz;
452
+ const lag = 0.5 * gn * h;
453
+ const w0n = lv[0] * nx + lv[1] * ny + lv[2] * nz - gn * dt + lag;
454
+
455
+ // Approaching at impact, by construction: the root on the closing side.
456
+ const disc = w0n * w0n + 2 * gn * dn;
457
+ const wn = -Math.sqrt(disc > 0 ? disc : 0);
458
+
459
+ const closing = w0n + wn;
460
+ let tau = closing < 0 ? 2 * dn / closing : frac * dt;
461
+ if (!Number.isFinite(tau)) tau = frac * dt;
462
+ if (tau < 0) tau = 0;
463
+ else if (tau > dt) tau = dt;
464
+
465
+ const lost = dt - tau;
466
+ lv[0] -= gx * lost;
467
+ lv[1] -= gy * lost;
468
+ lv[2] -= gz * lost;
469
+
470
+ _impact_lag = lag - 0.5 * fn * h;
471
+ }
472
+
473
+ /**
474
+ * How fast the body the sweep struck fell along the contact normal through
475
+ * the step: its acceleration along `n` over the solve, from the velocity
476
+ * change {@link ccd_resolve} read off before its first impulse, kept between
477
+ * none and its own gravity's. Zero for a static or kinematic blocker, and for
478
+ * a body that was not awake when the step began.
479
+ *
480
+ * A blocker in free flight runs half a substep of its gravity ahead of its
481
+ * stored velocity, as the mover does; one resting on something does not. So
482
+ * the fall decides how much of the blocker's lag the impulse takes off the
483
+ * mover's ({@link ccd_velocity_at_impact}): with each body's own, an elastic
484
+ * impulse keeps the pair's free-flight energy. With the mover's lag alone, a
485
+ * ball striking a falling box raised the pair's energy by up to 2.3% at 30 Hz
486
+ * with one substep.
487
+ *
488
+ * It decides no more than that. afc18e2b1 also took it off the mover's rewind,
489
+ * so that two bodies falling together collided as they would with gravity off.
490
+ * That left the mover at the pose of the impact with the velocity of the end
491
+ * of the step, and the pair's free-flight energy rose by 0.19% to 0.78% a
492
+ * strike. The mover is rewound by its own gravity instead, as Box3D does, and
493
+ * loses the rest of the step: the pair, now half a step apart in time, comes
494
+ * out of an elastic impact with 0.953 to 1.014 times the energy it had about
495
+ * its centre of mass, never more in all. A crate resting on the floor still
496
+ * does not fall: a ball bouncing on it comes back to 0.994 to 0.996 of its
497
+ * height.
498
+ *
499
+ * The rest of the blocker's velocity change is its contacts', which act on it
500
+ * and on something else, never on the mover: hence the clamp. The impulses of
501
+ * this pass are left out altogether: a ball that struck a box earlier in the
502
+ * pass set it moving, it did not make it fall.
503
+ *
504
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
505
+ * @param {PhysicsSurfacePoint} hit the sweep result that produced the clamp
506
+ * @param {number} dt the step's length
507
+ * @param {number} captured how many of the awake set's first positions the
508
+ * step captured a start-of-step velocity for
509
+ * @returns {number}
510
+ */
511
+ function blocker_fall(system, hit, dt, captured) {
512
+ const blocker_id = hit.body_id;
513
+ const storage = system.storage;
514
+ if (blocker_id < 0 || !storage.is_valid(blocker_id) || !(dt > 0)) return 0;
515
+
516
+ const idx = body_id_index(blocker_id);
517
+ const blocker = system.__bodies[idx];
518
+ if (blocker === undefined || blocker.kind !== BodyKind.Dynamic) return 0;
519
+
520
+ // A body woken after the step began — by an impulse earlier in this
521
+ // pass, say — kept still until then, and its velocity change was never
522
+ // read.
523
+ const position = storage.awake_position_of(idx);
524
+ if (position === BODY_INDEX_ABSENT || position >= captured) return 0;
525
+
526
+ const nx = hit.normal[0], ny = hit.normal[1], nz = hit.normal[2];
527
+ const g = system.gravity;
528
+ const gn = (g[0] * nx + g[1] * ny + g[2] * nz) * blocker.gravityScale;
529
+
530
+ const change = system.__ccd_start_vel;
531
+ const b = idx * 3;
532
+ const an = (change[b] * nx + change[b + 1] * ny + change[b + 2] * nz) / dt;
533
+
534
+ const lo = gn < 0 ? gn : 0;
535
+ const hi = gn < 0 ? 0 : gn;
536
+ return an < lo ? lo : (an > hi ? hi : an);
537
+ }
538
+
539
+ /**
540
+ * How far the swept collider reaches from its centre toward what it struck,
541
+ * along the contact normal `n`: the height of its centre over the struck
542
+ * surface where they touch. A body that ends its step this far past the
543
+ * contact pose has its centre on the surface's far side.
544
+ *
545
+ * @param {import("../../../core/geom/3d/shape/AbstractShape3D.js").AbstractShape3D} shape
546
+ * @param {Transform64} tr the collider's transform
547
+ * @param {ArrayLike<number>} n the blocker's unit outward normal, toward the body
548
+ * @returns {number}
549
+ */
550
+ function contact_depth_reach(shape, tr, n) {
551
+ _clamped.setup_components(
552
+ shape,
553
+ tr.translation_x, tr.translation_y, tr.translation_z,
554
+ tr.rotation_x, tr.rotation_y, tr.rotation_z, tr.rotation_w
555
+ );
556
+ _witness_direction[0] = -n[0];
557
+ _witness_direction[1] = -n[1];
558
+ _witness_direction[2] = -n[2];
559
+ _clamped.support(_witness, 0, _witness_direction, 0);
560
+ return (tr.translation_x - _witness[0]) * n[0]
561
+ + (tr.translation_y - _witness[1]) * n[1]
562
+ + (tr.translation_z - _witness[2]) * n[2];
563
+ }
564
+
565
+ /**
566
+ * If the sweep's hit is a CONVEX collider the swept body is sliding along —
567
+ * the body started the step within {@link CCD_MIN_SWEEP_DISTANCE} of it, ends
568
+ * the step no more than {@link CCD_CONTACT_SLOP} past it, and keeps its centre
569
+ * on its own side — add that collider to {@link _slid_along}, so the next
570
+ * sweep of the body steps past it, and say so.
571
+ *
572
+ * A convex collider is safe to step past: it lies wholly on the far side of
573
+ * the plane the body slides along, which the body crosses by no more than the
574
+ * slop. A concave one is not — the triangle the body slides on shares its
575
+ * collider with the walls it may run into — and {@link shape_cast} already
576
+ * steps past such triangles one by one.
577
+ *
578
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
579
+ * @param {PhysicsSurfacePoint} hit the sweep's result
580
+ * @param {import("../../../core/geom/3d/shape/AbstractShape3D.js").AbstractShape3D} shape the swept shape
581
+ * @param {Transform64} tr the swept collider's transform, at the end pose
582
+ * @param {number} sx start of the sweep
583
+ * @param {number} sy
584
+ * @param {number} sz
585
+ * @param {number} ex end of the sweep
586
+ * @param {number} ey
587
+ * @param {number} ez
588
+ * @returns {boolean} true when a collider was added, and the body should be swept again
589
+ */
590
+ function step_past_slid_along(system, hit, shape, tr, sx, sy, sz, ex, ey, ez) {
591
+ const hp = hit.position;
592
+ const n = hit.normal;
593
+ const overshoot = (hp[0] - ex) * n[0] + (hp[1] - ey) * n[1] + (hp[2] - ez) * n[2];
594
+ const closed = (sx - hp[0]) * n[0] + (sy - hp[1]) * n[1] + (sz - hp[2]) * n[2];
595
+ if (!(closed <= CCD_MIN_SWEEP_DISTANCE && overshoot <= CCD_CONTACT_SLOP)) return false;
596
+ if (!(overshoot < contact_depth_reach(shape, tr, n))) return false;
597
+
598
+ const blocker_id = hit.body_id;
599
+ if (blocker_id < 0 || !system.storage.is_valid(blocker_id)) return false;
600
+ const list = system.__body_collider_lists[body_id_index(blocker_id)];
601
+ if (list === undefined) return false;
602
+
603
+ const before = _slid_along_count;
604
+ for (let i = 0; i < list.length && _slid_along_count < CCD_MAX_SLID_ALONG; i++) {
605
+ const entry = list[i];
606
+ if (entry.entity === hit.collider_entity && entry.collider.shape.is_convex !== false) {
607
+ _slid_along[_slid_along_count++] = entry.collider;
608
+ }
609
+ }
610
+ return _slid_along_count > before;
611
+ }
612
+
613
+ /**
614
+ * Empty {@link _slid_along}, releasing the colliders it held.
615
+ */
616
+ function clear_slid_along() {
617
+ for (let i = 0; i < _slid_along_count; i++) _slid_along[i] = null;
618
+ _slid_along_count = 0;
619
+ }
620
+
621
+ /**
622
+ * Whether the collider the sweep struck is concave — a mesh, a heightmap —
623
+ * which {@link shape_cast} sweeps triangle by triangle, so that what it struck
624
+ * is one triangle of a larger surface. The struck collider is the one on the
625
+ * entity the hit names (`collider_entity`). Asked of the whole body instead, a
626
+ * body with a mesh anywhere on it took the mesh rule for its convex parts too:
627
+ * a box face striking a 0.2 m cube that shared its body with a mesh put the
628
+ * impulse beside the cube, which spun off at 502 rad/s.
629
+ *
630
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
631
+ * @param {PhysicsSurfacePoint} hit the sweep result that produced the clamp
632
+ * @returns {boolean}
633
+ */
634
+ function struck_collider_is_concave(system, hit) {
635
+ const blocker_id = hit.body_id;
636
+ if (blocker_id < 0 || !system.storage.is_valid(blocker_id)) return false;
637
+
638
+ const list = system.__body_collider_lists[body_id_index(blocker_id)];
639
+ if (list === undefined) return false;
640
+
641
+ const entity = hit.collider_entity;
642
+ for (let i = 0; i < list.length; i++) {
643
+ const entry = list[i];
644
+ if (entry.entity === entity && entry.collider.shape.is_convex === false) return true;
645
+ }
646
+ return false;
647
+ }
648
+
649
+ /**
650
+ * The contact the sweep just found, as the response and the report both use
651
+ * it: its point into {@link _witness}, the pair's combined friction and
652
+ * restitution into {@link _friction} / {@link _restitution}.
653
+ *
654
+ * The point is the middle of where the two FEATURES facing each other overlap
655
+ * in the contact plane: the mover's around −normal at its clamped pose (a
656
+ * sphere's near pole, a box's leading corner, edge or face) and the struck
657
+ * surface's around +normal ({@link shape_cast_struck_support}). Each feature
658
+ * is sampled by {@link WITNESS_SAMPLES} supports along directions tilted
659
+ * {@link WITNESS_TILT} off the normal all round it — every one lands on an
660
+ * extreme point of the feature, so a vertex stays a vertex while an edge or a
661
+ * face spreads to its extent — and the point is the middle of the overlap of
662
+ * the two extents. A vertex against a face is the vertex; a small face against
663
+ * a large one is the small face's middle.
664
+ *
665
+ * A single support along −normal is a corner of whatever feature faces the
666
+ * blocker, and the impulse went in at that point: a box striking a box face to
667
+ * face took it at a corner of its face and spun off at 95 rad/s about two axes,
668
+ * keeping 52 of 60 m/s where the even split leaves 30. The mover's feature
669
+ * alone is not enough either: a box face striking a small ball 0.15 off the
670
+ * face's middle put the impulse at the face's middle, beside the ball, which
671
+ * spun off at 380 rad/s while the box kept straight on.
672
+ *
673
+ * Except on the FACE of a concave collider's triangle
674
+ * ({@link struck_collider_is_concave}): the struck feature is then the one
675
+ * triangle the sweep met, a fragment of a surface its neighbouring triangles
676
+ * continue, and the mover's feature alone places the contact. Overlapped with
677
+ * the triangle, a box's face striking a free plate of 0.1 m mesh cells flat and
678
+ * centred took the impulse under the triangle's middle, 0.25 off on both axes:
679
+ * box and plate spun at 228 rad/s between them and the box kept 93.75 of its
680
+ * 120 m/s, where the centred impulse leaves 40. A triangle met on an edge or a
681
+ * vertex keeps the overlap: a box's face striking the apex of a mesh pyramid
682
+ * 0.15 off its middle, placed by the box's face alone, put the impulse beside
683
+ * the apex — the pyramid spun at 54 rad/s and the box not at all, where the
684
+ * apex turns the box at 206 rad/s and leaves the pyramid still.
685
+ *
686
+ * Materials are combined exactly as `dispatch_pair` does, from the blocker's
687
+ * primary collider; an invalid blocker has none, and gets zero.
688
+ *
689
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
690
+ * @param {Collider} collider the swept (primary) collider
691
+ * @param {Transform64} tr the swept collider's transform, already clamped to
692
+ * the contact pose
693
+ * @param {PhysicsSurfacePoint} hit the sweep result that produced the clamp
694
+ */
695
+ function ccd_contact(system, collider, tr, hit) {
696
+ const n = hit.normal;
697
+ const nx = n[0], ny = n[1], nz = n[2];
698
+ _clamped.setup_components(
699
+ collider.shape,
700
+ tr.translation_x, tr.translation_y, tr.translation_z,
701
+ tr.rotation_x, tr.rotation_y, tr.rotation_z, tr.rotation_w
702
+ );
703
+
704
+ // A tangent basis (t1, t2) of the contact plane: t1 from the world axis
705
+ // least aligned with n.
706
+ const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);
707
+ let t1x, t1y, t1z;
708
+ if (ax <= ay && ax <= az) { t1x = 0; t1y = nz; t1z = -ny; }
709
+ else if (ay <= az) { t1x = -nz; t1y = 0; t1z = nx; }
710
+ else { t1x = ny; t1y = -nx; t1z = 0; }
711
+ const t1_inv = 1 / Math.sqrt(t1x * t1x + t1y * t1y + t1z * t1z);
712
+ t1x *= t1_inv; t1y *= t1_inv; t1z *= t1_inv;
713
+ const t2x = ny * t1z - nz * t1y;
714
+ const t2y = nz * t1x - nx * t1z;
715
+ const t2z = nx * t1y - ny * t1x;
716
+
717
+ // Both facing features, sampled, in contact-plane coordinates (u, v) and
718
+ // height h along n: the mover's around −n, the struck surface's around +n.
719
+ // Of the struck one also the spread, taken about its first sample so that
720
+ // coordinates far from the origin do not cancel it away.
721
+ let ua0 = Infinity, ua1 = -Infinity, va0 = Infinity, va1 = -Infinity, ha = 0;
722
+ let ub0 = Infinity, ub1 = -Infinity, vb0 = Infinity, vb1 = -Infinity;
723
+ let bu_ref = 0, bv_ref = 0, su = 0, sv = 0, suu = 0, svv = 0, suv = 0;
724
+ for (let k = 0; k < WITNESS_SAMPLES; k++) {
725
+ const angle = WITNESS_PHASE + k * (2 * Math.PI / WITNESS_SAMPLES);
726
+ const c = Math.cos(angle) * WITNESS_TILT;
727
+ const s = Math.sin(angle) * WITNESS_TILT;
728
+ const ox = c * t1x + s * t2x, oy = c * t1y + s * t2y, oz = c * t1z + s * t2z;
729
+
730
+ _witness_direction[0] = -nx + ox;
731
+ _witness_direction[1] = -ny + oy;
732
+ _witness_direction[2] = -nz + oz;
733
+ _clamped.support(_witness, 0, _witness_direction, 0);
734
+ const au = _witness[0] * t1x + _witness[1] * t1y + _witness[2] * t1z;
735
+ const av = _witness[0] * t2x + _witness[1] * t2y + _witness[2] * t2z;
736
+ if (au < ua0) ua0 = au;
737
+ if (au > ua1) ua1 = au;
738
+ if (av < va0) va0 = av;
739
+ if (av > va1) va1 = av;
740
+ ha += _witness[0] * nx + _witness[1] * ny + _witness[2] * nz;
741
+
742
+ _witness_direction[0] = nx + ox;
743
+ _witness_direction[1] = ny + oy;
744
+ _witness_direction[2] = nz + oz;
745
+ shape_cast_struck_support(_witness, 0, _witness_direction, 0);
746
+ const bu = _witness[0] * t1x + _witness[1] * t1y + _witness[2] * t1z;
747
+ const bv = _witness[0] * t2x + _witness[1] * t2y + _witness[2] * t2z;
748
+ if (bu < ub0) ub0 = bu;
749
+ if (bu > ub1) ub1 = bu;
750
+ if (bv < vb0) vb0 = bv;
751
+ if (bv > vb1) vb1 = bv;
752
+
753
+ if (k === 0) {
754
+ bu_ref = bu;
755
+ bv_ref = bv;
756
+ }
757
+ const du = bu - bu_ref, dv = bv - bv_ref;
758
+ su += du;
759
+ sv += dv;
760
+ suu += du * du;
761
+ svv += dv * dv;
762
+ suv += du * dv;
763
+ }
764
+ ha /= WITNESS_SAMPLES;
765
+
766
+ // A concave collider's struck feature is one triangle. Met on its FACE, it
767
+ // is a fragment of a surface its neighbours continue, and the mover's
768
+ // feature alone places the contact; met on an edge or a vertex, it is a
769
+ // feature in its own right, and the overlap below places it as on a convex
770
+ // body. The samples span an area only on the face: the spread across their
771
+ // thinnest direction is nothing for an edge or a vertex.
772
+ if (struck_collider_is_concave(system, hit)) {
773
+ const inv = 1 / WITNESS_SAMPLES;
774
+ const mu = su * inv, mv = sv * inv;
775
+ const cuu = suu * inv - mu * mu;
776
+ const cvv = svv * inv - mv * mv;
777
+ const cuv = suv * inv - mu * mv;
778
+ const mean = 0.5 * (cuu + cvv);
779
+ const dev = Math.sqrt(0.25 * (cuu - cvv) * (cuu - cvv) + cuv * cuv);
780
+ if (mean - dev > FACE_SPREAD * (mean + dev)) {
781
+ ub0 = vb0 = -Infinity;
782
+ ub1 = vb1 = Infinity;
783
+ }
784
+ }
785
+
786
+ // The middle of where the two features' extents overlap (or of the gap
787
+ // between them, the same expression): a vertex against a face is the
788
+ // vertex, a small face against a large one the small face's middle.
789
+ const u = 0.5 * ((ua0 > ub0 ? ua0 : ub0) + (ua1 < ub1 ? ua1 : ub1));
790
+ const v = 0.5 * ((va0 > vb0 ? va0 : vb0) + (va1 < vb1 ? va1 : vb1));
791
+ _witness[0] = u * t1x + v * t2x + ha * nx;
792
+ _witness[1] = u * t1y + v * t2y + ha * ny;
793
+ _witness[2] = u * t1z + v * t2z + ha * nz;
794
+
795
+ _friction = 0;
796
+ _restitution = 0;
797
+
798
+ const blocker_id = hit.body_id;
799
+ if (blocker_id < 0 || !system.storage.is_valid(blocker_id)) return;
800
+
801
+ const blocker_collider = system.__primary_collider(body_id_index(blocker_id));
802
+ if (blocker_collider !== null
803
+ && collider.friction !== undefined
804
+ && blocker_collider.friction !== undefined
805
+ ) {
806
+ _friction = combine_friction(collider.friction, blocker_collider.friction);
807
+ _restitution = combine_restitution(collider.restitution, blocker_collider.restitution);
808
+ }
809
+ }
810
+
811
+ /**
812
+ * Respond to the impact the sweep just resolved, at the moment of impact: one
813
+ * normal impulse at the contact point {@link ccd_contact} found, along the
814
+ * sweep's normal, and Coulomb friction against the contact point's slide
815
+ * ({@link ccd_friction}). The mover's velocity has already been rewound to the
816
+ * time of impact ({@link ccd_velocity_at_impact}).
817
+ *
818
+ * The normal velocity the response works on is the body's MOTION, the stored
819
+ * velocity plus {@link _impact_lag}: the stored velocity runs half a substep
820
+ * behind the motion, and the bounce has to send the motion away at `e` times
821
+ * its approach for the integrator's next substeps to retrace it. Reflecting the
822
+ * stored velocity drops the lag on the way in and again on the way out: an
823
+ * e = 1 ball lost 1.3% of its height every bounce from 2 m, and 13% from 7 cm
824
+ * at 30 Hz.
825
+ *
826
+ * Only an APPROACH is answered — a pair already separating along the normal
827
+ * (the solver's own restitution got there first, say) is left alone, so the
828
+ * response never doubles one the discrete step already gave. The approach must
829
+ * be faster than `PhysicsSystem.restitutionThreshold` to bounce, the rule
830
+ * `prepare_contacts` applies, so a slow impact comes to rest instead of
831
+ * buzzing.
832
+ *
833
+ * Against a DYNAMIC blocker the impulse is shared ({@link ccd_respond_shared}):
834
+ * stopping the mover alone, as the pass did, left the blocker where it was and
835
+ * threw the mover's momentum away — a 1 kg ball into a resting 1 kg box
836
+ * stopped at its face and the box never moved.
837
+ *
838
+ * Against an immovable blocker — static, kinematic, a sleeper the impact is too
839
+ * weak to wake, or one the sweep can no longer name — only the mover's
840
+ * velocity changes, and only linearly: its centre's normal motion relative to
841
+ * the blocker's surface becomes `−e` times what it was. That is the rigid-body
842
+ * answer for a sphere and for a body that cannot rotate. For a box struck on a
843
+ * corner it is not — the impulse there would also turn it — and that answer
844
+ * was measured and declined: a 60 m/s box flung into up to 330 rad/s of spin
845
+ * by a corner strike on a 2 cm wall turned through it within the next steps in
846
+ * 7 of 18 cases, the linear sweep holding its orientation fixed; with the
847
+ * linear response, 0 of 18. Friction does turn it, bounded by what stops the
848
+ * contact point's slide: tilted, spinning boxes fired obliquely at 60 m/s into
849
+ * a 2 cm wall of μ 0.5 or 1 reached 128 rad/s and turned through it in 0 of
850
+ * 162 cases.
851
+ *
852
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
853
+ * @param {RigidBody} rb the swept body
854
+ * @param {Transform64} body_tr the swept body's own transform (its centre of
855
+ * mass), already clamped
856
+ * @param {PhysicsSurfacePoint} hit the sweep result that produced the clamp
857
+ */
858
+ function ccd_respond(system, rb, body_tr, hit) {
859
+ const n = hit.normal;
860
+ const nx = n[0], ny = n[1], nz = n[2];
861
+
862
+ const blocker_id = hit.body_id;
863
+ const valid = blocker_id >= 0 && system.storage.is_valid(blocker_id);
864
+ const blocker_idx = valid ? body_id_index(blocker_id) : -1;
865
+ const blocker = valid ? system.__bodies[blocker_idx] : undefined;
866
+ const blocker_tr = valid ? system.__transforms[blocker_idx] : undefined;
867
+ const known = blocker !== undefined && blocker_tr !== undefined;
868
+
869
+ if (known && blocker.kind === BodyKind.Dynamic
870
+ && ccd_respond_shared(system, rb, body_tr, blocker, blocker_idx, blocker_tr, nx, ny, nz)) {
871
+ return;
872
+ }
873
+
874
+ // The blocker's surface velocity at the contact point: a kinematic body's
875
+ // own motion; none for a static body, nor for a sleeper (at rest by the
876
+ // sleep invariant).
877
+ const px = _witness[0], py = _witness[1], pz = _witness[2];
878
+ let vbx = 0, vby = 0, vbz = 0;
879
+ if (known && (blocker.kind === BodyKind.KinematicVelocity || blocker.kind === BodyKind.KinematicPosition)) {
880
+ const bl = blocker.linearVelocity;
881
+ const ba = blocker.angularVelocity;
882
+ const rx = px - blocker_tr.translation_x;
883
+ const ry = py - blocker_tr.translation_y;
884
+ const rz = pz - blocker_tr.translation_z;
885
+ vbx = bl[0] + ba[1] * rz - ba[2] * ry;
886
+ vby = bl[1] + ba[2] * rx - ba[0] * rz;
887
+ vbz = bl[2] + ba[0] * ry - ba[1] * rx;
888
+ }
889
+
890
+ const lv = rb.linearVelocity;
891
+ const wn = (lv[0] - vbx) * nx + (lv[1] - vby) * ny + (lv[2] - vbz) * nz + _impact_lag;
892
+ if (!(wn < 0)) return;
893
+
894
+ const e = wn < -system.restitutionThreshold ? _restitution : 0;
895
+ const dv = -(1 + e) * wn;
896
+ lv[0] += dv * nx;
897
+ lv[1] += dv * ny;
898
+ lv[2] += dv * nz;
899
+
900
+ const inv_m = inverse_mass(rb);
901
+ if (inv_m > 0) {
902
+ ccd_friction(system, rb, body_tr, null, null, vbx, vby, vbz, dv / inv_m, nx, ny, nz);
903
+ }
904
+ }
905
+
906
+ /**
907
+ * Coulomb friction at the impact: a tangential impulse at the contact point
908
+ * {@link ccd_contact} found, against the slide of the mover's contact point
909
+ * over the blocker's surface, of at most `μ·j_n` — `μ` the pair's combined
910
+ * friction ({@link _friction}), `j_n` the normal impulse just applied. Within
911
+ * that bound it stops the slide: `j_t = s / K_t`, `s` the slide's speed and
912
+ * `K_t` the effective mass along it, `1/m_A + (r_A × t)·I_A⁻¹(r_A × t)` plus
913
+ * the blocker's own two terms when it is free. Applied at the contact point,
914
+ * linear and angular, to the mover and (oppositely) to a free blocker.
915
+ *
916
+ * The slide is the contact points' relative velocity after the normal impulse,
917
+ * spin included, less its normal part; the blocker's surface moves with a
918
+ * kinematic body's own motion and with a free body's.
919
+ *
920
+ * An impulse that at most stops the slide takes energy and never adds it, and
921
+ * one with its opposite on the other body keeps momentum about any point. With
922
+ * the normal impulse alone, whatever ran along the surface ran on: a ball shot
923
+ * straight down at 150 m/s onto a μ 0.5 slope of 5° or 10° kept its 13 or
924
+ * 26 m/s along it and went 11 or 23 m in a second, and a ball spinning at 20
925
+ * rad/s into a μ 0.5 wall left with all of it.
926
+ *
927
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
928
+ * @param {RigidBody} rb the swept body
929
+ * @param {Transform64} body_tr its transform, already clamped
930
+ * @param {RigidBody|null} other a free blocker sharing the impulse, or null
931
+ * @param {Transform64|null} other_tr its transform
932
+ * @param {number} vbx the surface's velocity at the contact point, when `other` is null
933
+ * @param {number} vby
934
+ * @param {number} vbz
935
+ * @param {number} jn the normal impulse, ≥ 0
936
+ * @param {number} nx the blocker's outward normal, toward the mover
937
+ * @param {number} ny
938
+ * @param {number} nz
939
+ */
940
+ function ccd_friction(system, rb, body_tr, other, other_tr, vbx, vby, vbz, jn, nx, ny, nz) {
941
+ const limit = _friction * jn;
942
+ if (!(limit > 0)) return;
943
+
944
+ const px = _witness[0], py = _witness[1], pz = _witness[2];
945
+
946
+ const lv = rb.linearVelocity;
947
+ const av = rb.angularVelocity;
948
+ const rax = px - body_tr.translation_x;
949
+ const ray = py - body_tr.translation_y;
950
+ const raz = pz - body_tr.translation_z;
951
+
952
+ let rbx = 0, rby = 0, rbz = 0;
953
+ if (other !== null) {
954
+ const bl = other.linearVelocity;
955
+ const ba = other.angularVelocity;
956
+ rbx = px - other_tr.translation_x;
957
+ rby = py - other_tr.translation_y;
958
+ rbz = pz - other_tr.translation_z;
959
+ vbx = bl[0] + ba[1] * rbz - ba[2] * rby;
960
+ vby = bl[1] + ba[2] * rbx - ba[0] * rbz;
961
+ vbz = bl[2] + ba[0] * rby - ba[1] * rbx;
962
+ }
963
+
964
+ // The contact points' relative velocity, and its part along the surface.
965
+ let ux = lv[0] + av[1] * raz - av[2] * ray - vbx;
966
+ let uy = lv[1] + av[2] * rax - av[0] * raz - vby;
967
+ let uz = lv[2] + av[0] * ray - av[1] * rax - vbz;
968
+ const un = ux * nx + uy * ny + uz * nz;
969
+ ux -= un * nx;
970
+ uy -= un * ny;
971
+ uz -= un * nz;
972
+
973
+ const slide = Math.sqrt(ux * ux + uy * uy + uz * uz);
974
+ if (!(slide > 0)) return;
975
+ const tx = ux / slide, ty = uy / slide, tz = uz / slide;
976
+
977
+ let k = inverse_mass(rb) + angular_term(rb, body_tr, rax, ray, raz, tx, ty, tz);
978
+ if (other !== null) {
979
+ k += inverse_mass(other) + angular_term(other, other_tr, rbx, rby, rbz, tx, ty, tz);
980
+ }
981
+ if (!(k > 0)) return;
982
+
983
+ const stop = slide / k;
984
+ const jt = stop < limit ? stop : limit;
985
+
986
+ _impulse[0] = -tx * jt;
987
+ _impulse[1] = -ty * jt;
988
+ _impulse[2] = -tz * jt;
989
+ system.applyImpulseAt(rb, body_tr, _impulse, _witness);
990
+
991
+ if (other !== null) {
992
+ _impulse[0] = -_impulse[0];
993
+ _impulse[1] = -_impulse[1];
994
+ _impulse[2] = -_impulse[2];
995
+ system.applyImpulseAt(other, other_tr, _impulse, _witness);
996
+ }
997
+ }
998
+
999
+ /**
1000
+ * The impulse {@link ccd_respond} shares with a dynamic blocker:
1001
+ * `j = −(1 + e)·w_n / K`, `w_n` the normal velocity of the contact point of the
1002
+ * mover relative to that of the blocker (taken as their relative motion, the
1003
+ * stored velocities plus {@link _impact_lag}, see {@link ccd_respond}), and
1004
+ * `K = 1/m_A + 1/m_B + (r_A × n)·I_A⁻¹(r_A × n) + (r_B × n)·I_B⁻¹(r_B × n)`,
1005
+ * applied to both bodies at the contact point, linear and angular, and then
1006
+ * Coulomb friction between them ({@link ccd_friction}), also shared.
1007
+ *
1008
+ * A SLEEPING blocker is woken only by an impulse that leaves it moving faster
1009
+ * than the sleep test lets a body sleep at ({@link PhysicsSystem#sleepVelocitySqrThreshold}),
1010
+ * judged by the sleep test's own metric: the speed of the body's far end,
1011
+ * `|v|² + |ω|²·max(extent, 1)²` ({@link body_extent}). A weaker one is
1012
+ * declined — the sleeper stands as an anchor, the way the solver gathers a
1013
+ * sleeping body — because the sleep test would only zero it again a moment
1014
+ * later, and because a body ground against a sleeper re-strikes it every step
1015
+ * for nothing: waking it each time left it flickering awake and asleep for as
1016
+ * long as the grinding lasted. Judged on `|ω|²` alone, a 4 g pellet at 100 m/s
1017
+ * into the tip of a sleeping 20 m plank read 0.0017 where the tip would move at
1018
+ * 0.12 m/s (0.0145 against the threshold's 0.01): the plank stood, and the
1019
+ * pellet's momentum went nowhere.
1020
+ *
1021
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
1022
+ * @param {RigidBody} rb
1023
+ * @param {Transform64} body_tr
1024
+ * @param {RigidBody} blocker
1025
+ * @param {number} blocker_idx the blocker's storage index
1026
+ * @param {Transform64} blocker_tr
1027
+ * @param {number} nx blocker's outward normal, toward the mover
1028
+ * @param {number} ny
1029
+ * @param {number} nz
1030
+ * @returns {boolean} false when declined — the caller treats the blocker as
1031
+ * immovable
1032
+ */
1033
+ function ccd_respond_shared(system, rb, body_tr, blocker, blocker_idx, blocker_tr, nx, ny, nz) {
1034
+ const px = _witness[0], py = _witness[1], pz = _witness[2];
1035
+
1036
+ const lv = rb.linearVelocity;
1037
+ const av = rb.angularVelocity;
1038
+ const rax = px - body_tr.translation_x;
1039
+ const ray = py - body_tr.translation_y;
1040
+ const raz = pz - body_tr.translation_z;
1041
+
1042
+ const bl = blocker.linearVelocity;
1043
+ const ba = blocker.angularVelocity;
1044
+ const rbx = px - blocker_tr.translation_x;
1045
+ const rby = py - blocker_tr.translation_y;
1046
+ const rbz = pz - blocker_tr.translation_z;
1047
+
1048
+ const wn = (lv[0] + av[1] * raz - av[2] * ray - (bl[0] + ba[1] * rbz - ba[2] * rby)) * nx
1049
+ + (lv[1] + av[2] * rax - av[0] * raz - (bl[1] + ba[2] * rbx - ba[0] * rbz)) * ny
1050
+ + (lv[2] + av[0] * ray - av[1] * rax - (bl[2] + ba[0] * rby - ba[1] * rbx)) * nz
1051
+ + _impact_lag;
1052
+ if (!(wn < 0)) return true;
1053
+
1054
+ const e = wn < -system.restitutionThreshold ? _restitution : 0;
1055
+
1056
+ const inv_mb = inverse_mass(blocker);
1057
+ const k = inverse_mass(rb) + inv_mb
1058
+ + angular_term(rb, body_tr, rax, ray, raz, nx, ny, nz)
1059
+ + angular_term(blocker, blocker_tr, rbx, rby, rbz, nx, ny, nz);
1060
+ if (!(k > 0)) return true;
1061
+
1062
+ const j = -(1 + e) * wn / k;
1063
+
1064
+ if (blocker.sleepState !== SleepState.Awake) {
1065
+ // The blocker's velocity change: −j·n linearly, I⁻¹(r × −j·n) angularly.
1066
+ const dv = j * inv_mb;
1067
+ masked_inverse_inertia(blocker);
1068
+ world_inverse_inertia_apply_raw(
1069
+ _inertia_scratch, 0,
1070
+ _masked_inertia[0], _masked_inertia[1], _masked_inertia[2],
1071
+ blocker_tr.rotation_x, blocker_tr.rotation_y, blocker_tr.rotation_z, blocker_tr.rotation_w,
1072
+ -(rby * nz - rbz * ny) * j, -(rbz * nx - rbx * nz) * j, -(rbx * ny - rby * nx) * j
1073
+ );
1074
+ const w = _inertia_scratch;
1075
+ const extent = body_extent(system, blocker_idx, blocker_tr);
1076
+ const reach = extent > 1 ? extent : 1;
1077
+ if (dv * dv + (w[0] * w[0] + w[1] * w[1] + w[2] * w[2]) * reach * reach <= system.sleepVelocitySqrThreshold) {
1078
+ return false;
1079
+ }
1080
+ }
1081
+
1082
+ _impulse[0] = nx * j;
1083
+ _impulse[1] = ny * j;
1084
+ _impulse[2] = nz * j;
1085
+ system.applyImpulseAt(rb, body_tr, _impulse, _witness);
1086
+
1087
+ _impulse[0] = -_impulse[0];
1088
+ _impulse[1] = -_impulse[1];
1089
+ _impulse[2] = -_impulse[2];
1090
+ system.applyImpulseAt(blocker, blocker_tr, _impulse, _witness);
1091
+
1092
+ ccd_friction(system, rb, body_tr, blocker, blocker_tr, 0, 0, 0, j, nx, ny, nz);
1093
+
1094
+ return true;
1095
+ }
1096
+
1097
+ /**
1098
+ * A body's extent, metres: how far from its centre any of its colliders
1099
+ * reaches — each collider's local bounding-box corner radius plus the
1100
+ * collider's offset from the body — exactly as stage 2 of the step records it
1101
+ * in `PhysicsSystem.__body_extent` for the sleep test.
1102
+ *
1103
+ * Computed here from the colliders, not read from there: stage 2 writes the
1104
+ * AWAKE bodies only, and a sleeper's slot is not kept. Linking twelve more
1105
+ * bodies after a 20 m plank fell asleep grew the array, and the plank's slot
1106
+ * then read 0; a body linked asleep never had one written.
1107
+ *
1108
+ * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
1109
+ * @param {number} idx the body's storage index
1110
+ * @param {Transform64} body_tr the body's transform (its centre)
1111
+ * @returns {number}
1112
+ */
1113
+ function body_extent(system, idx, body_tr) {
1114
+ const list = system.__body_collider_lists[idx];
1115
+ if (list === undefined) return 0;
1116
+
1117
+ let extent = 0;
1118
+ for (let i = 0; i < list.length; i++) {
1119
+ const entry = list[i];
1120
+ entry.collider.shape.compute_bounding_box(_local_box);
1121
+
1122
+ const ex = -_local_box[0] > _local_box[3] ? -_local_box[0] : _local_box[3];
1123
+ const ey = -_local_box[1] > _local_box[4] ? -_local_box[1] : _local_box[4];
1124
+ const ez = -_local_box[2] > _local_box[5] ? -_local_box[2] : _local_box[5];
1125
+ const ct = entry.transform;
1126
+ const ox = ct.translation_x - body_tr.translation_x;
1127
+ const oy = ct.translation_y - body_tr.translation_y;
1128
+ const oz = ct.translation_z - body_tr.translation_z;
1129
+ const reach = Math.sqrt(ex * ex + ey * ey + ez * ez) + Math.sqrt(ox * ox + oy * oy + oz * oz);
1130
+
1131
+ if (reach > extent) extent = reach;
1132
+ }
1133
+ return extent;
1134
+ }
1135
+
1136
+ /**
1137
+ * @param {RigidBody} rb a dynamic body
1138
+ * @returns {number}
1139
+ */
1140
+ function inverse_mass(rb) {
1141
+ return rb.mass > 0 ? 1 / rb.mass : 0;
1142
+ }
1143
+
1144
+ /**
1145
+ * Write `rb`'s body-local inverse-inertia diagonal into {@link _masked_inertia}
1146
+ * with the `LockRot*` mask `PhysicsSystem#applyImpulseAt` (which applies the
1147
+ * impulse) and the solver gather use.
1148
+ *
1149
+ * @param {RigidBody} rb
1150
+ */
1151
+ function masked_inverse_inertia(rb) {
1152
+ const ii = rb.inverseInertiaLocal;
1153
+ const flags = rb.flags;
1154
+ _masked_inertia[0] = (flags & RigidBodyFlags.LockRotX) !== 0 ? 0 : ii[0];
1155
+ _masked_inertia[1] = (flags & RigidBodyFlags.LockRotY) !== 0 ? 0 : ii[1];
1156
+ _masked_inertia[2] = (flags & RigidBodyFlags.LockRotZ) !== 0 ? 0 : ii[2];
1157
+ }
1158
+
1159
+ /**
1160
+ * One body's angular share of a normal impulse's effective mass at lever arm
1161
+ * `r`: `(r × n)·I_w⁻¹(r × n)`.
1162
+ *
1163
+ * @param {RigidBody} rb
1164
+ * @param {Transform64} tr
1165
+ * @param {number} rx
1166
+ * @param {number} ry
1167
+ * @param {number} rz
1168
+ * @param {number} nx
1169
+ * @param {number} ny
1170
+ * @param {number} nz
1171
+ * @returns {number}
1172
+ */
1173
+ function angular_term(rb, tr, rx, ry, rz, nx, ny, nz) {
1174
+ masked_inverse_inertia(rb);
1175
+ return angular_effective_mass_raw(
1176
+ _masked_inertia[0], _masked_inertia[1], _masked_inertia[2],
1177
+ tr.rotation_x, tr.rotation_y, tr.rotation_z, tr.rotation_w,
1178
+ rx, ry, rz,
1179
+ nx, ny, nz,
1180
+ _inertia_scratch
1181
+ );
1182
+ }
1183
+
232
1184
  /**
233
1185
  * Record the impact the sweep just resolved as a contact on the pair's
234
1186
  * manifold, so this step's event diff reports it.
235
1187
  *
236
1188
  * ## Why the sweep has to report its own impacts
237
1189
  *
238
- * The clamp parks the body on the just-SEPARATING side of the TOI bisection —
239
- * {@link shape_cast} reports `t_lo`, the last sample proven NOT to overlap, and
240
- * that is exactly the property the clamp relies on. The discrete narrowphase
241
- * emits a contact only for STRICTLY POSITIVE penetration. So the pose CCD
242
- * produces is, by construction, the one pose the narrowphase calls "not
243
- * touching": a body stopped dead by the sweep raised no ContactBegin, and kept
1190
+ * The clamp parks the body clear of the surface or touching it:
1191
+ * {@link shape_cast} stops a convex blocker's advancement 1e-5 m short, and a
1192
+ * triangle face's closed-form time leaves the body on the face to within
1193
+ * 5e-16 m, either side. The discrete narrowphase emits a contact only for
1194
+ * STRICTLY POSITIVE penetration. So the pose CCD produces is one the
1195
+ * narrowphase calls "not touching", or calls touching only as the rounding
1196
+ * falls: a body stopped dead by the sweep raised no ContactBegin, and kept
244
1197
  * raising none for as long as it sat there.
245
1198
  *
246
1199
  * That it ever appeared to work at all was luck about which side of tangency
@@ -263,8 +1216,10 @@ export function ccd_sweep_segment(
263
1216
  *
264
1217
  * ## What is written
265
1218
  *
266
- * A single contact at depth ZERO. The sweep stopped the body ON the surface, so
267
- * the pair is touching and the penetration is nothing; that is the honest depth
1219
+ * A single contact at depth ZERO. The sweep stopped the body at the surface —
1220
+ * 1e-5 to 1.25e-5 m clear of a convex, on a triangle's face to within
1221
+ * 5e-16 m — so the
1222
+ * pair is touching and the penetration is nothing; that is the honest depth
268
1223
  * and the one the solver's `PENETRATION_SLOP`-gated position bias ignores.
269
1224
  * Both witness points are the same point — at a tangency the two surfaces meet
270
1225
  * there — and `feature_id` is 0, no stable cross-frame feature, same as the
@@ -284,14 +1239,13 @@ export function ccd_sweep_segment(
284
1239
  * manifold is the better one, and only an impact the discrete pass could not
285
1240
  * see is this pass's to report.
286
1241
  *
1242
+ * Reads the contact point and materials {@link ccd_contact} computed.
1243
+ *
287
1244
  * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
288
1245
  * @param {number} body_idx swept body's storage index
289
- * @param {Collider} collider the swept (primary) collider
290
- * @param {Transform64} tr the swept body's transform, already clamped to the
291
- * contact pose
292
1246
  * @param {PhysicsSurfacePoint} hit the sweep result that produced the clamp
293
1247
  */
294
- function record_ccd_contact(system, body_idx, collider, tr, hit) {
1248
+ function record_ccd_contact(system, body_idx, hit) {
295
1249
  const blocker_id = hit.body_id;
296
1250
 
297
1251
  const storage = system.storage;
@@ -315,33 +1269,8 @@ function record_ccd_contact(system, body_idx, collider, tr, hit) {
315
1269
  // swept body.
316
1270
  const n = hit.normal;
317
1271
 
318
- // Contact witness: the swept shape's own surface point facing the blocker,
319
- // which is its support along −n (a sphere's near pole, a box's leading
320
- // corner). Taking it from the MOVER rather than the blocker is what keeps it
321
- // near the actual contact patch — a large blocker's support along a face
322
- // axis is a corner metres away, which is why the narrowphase's EPA fallback
323
- // refuses support witnesses and falls back to body centres.
324
- _clamped.setup_components(
325
- collider.shape,
326
- tr.translation_x, tr.translation_y, tr.translation_z,
327
- tr.rotation_x, tr.rotation_y, tr.rotation_z, tr.rotation_w
328
- );
329
- _clamped.support(_witness, 0, -n[0], -n[1], -n[2]);
330
-
331
1272
  const wx = _witness[0], wy = _witness[1], wz = _witness[2];
332
1273
 
333
- // Per-contact materials, combined exactly as `dispatch_pair` does.
334
- const blocker_collider = system.__primary_collider(blocker_idx);
335
- let friction = 0;
336
- let restitution = 0;
337
- if (blocker_collider !== null
338
- && collider.friction !== undefined
339
- && blocker_collider.friction !== undefined
340
- ) {
341
- friction = combine_friction(collider.friction, blocker_collider.friction);
342
- restitution = combine_restitution(collider.restitution, blocker_collider.restitution);
343
- }
344
-
345
1274
  // The stored normal points from the slot's OWN body B toward its body A.
346
1275
  const s = self_is_a ? 1 : -1;
347
1276
 
@@ -351,7 +1280,7 @@ function record_ccd_contact(system, body_idx, collider, tr, hit) {
351
1280
  wx, wy, wz,
352
1281
  n[0] * s, n[1] * s, n[2] * s,
353
1282
  0, 0,
354
- friction, restitution,
1283
+ _friction, _restitution,
355
1284
  );
356
1285
 
357
1286
  const w = _written_count * 3;
@@ -398,12 +1327,13 @@ export function ccd_release_contacts(system) {
398
1327
  * Post-solve continuous-collision pass over the awake set. For each awake
399
1328
  * Dynamic body flagged {@link RigidBodyFlags.CCD} that moved more than
400
1329
  * {@link CCD_MIN_SWEEP_DISTANCE} this step, sweep its primary collider along the
401
- * step's net translation and stop it at the first blocker (clamp pose + remove
402
- * inbound normal velocity).
1330
+ * step's net translation and stop it at the first blocker (clamp pose + the
1331
+ * impact's response, {@link ccd_respond}).
403
1332
  *
404
1333
  * Start-of-step positions are captured into `system.__ccd_start_pos` (3 doubles
405
- * per body index) before the substep loop; this pass reads the final pose from
406
- * the live Transform64.
1334
+ * per body index) before the substep loop, and the start-of-step velocities of
1335
+ * the awake dynamic bodies into `system.__ccd_start_vel`; this pass reads the
1336
+ * final pose from the live Transform64.
407
1337
  *
408
1338
  * Bodies are processed in ENTITY order, not awake-list order. CCD order is
409
1339
  * outcome-coupled: an earlier body's clamp moves the pose a later body's
@@ -413,25 +1343,47 @@ export function ccd_release_contacts(system) {
413
1343
  * state need not share; entity order is derivable from state alone — the
414
1344
  * determinism contract.
415
1345
  *
1346
+ * Returns how many bodies the pass CLAMPED — moved back from the pose the step
1347
+ * integrated them to — with their storage indices in {@link ccd_clamped_bodies}.
1348
+ * Whatever the step already published from those poses is stale.
1349
+ *
416
1350
  * @param {import("../ecs/PhysicsSystem.js").PhysicsSystem} system
1351
+ * @param {number} dt the step's length, seconds
1352
+ * @param {number} h the integrator's substep length, seconds
1353
+ * @param {number} captured how many of the awake set's first positions the
1354
+ * step captured start-of-step state for — the bodies awake when it began
1355
+ * @returns {number} clamped body count
417
1356
  */
418
- export function ccd_resolve(system) {
1357
+ export function ccd_resolve(system, dt, h, captured) {
419
1358
  // Each pass owns its own report list. Dropped rather than carried if a
420
1359
  // caller never got round to releasing the previous one, so a slot id can
421
1360
  // never be cleared a step after it was written (or for a pair that has
422
1361
  // since been reallocated onto it).
423
1362
  _written_count = 0;
424
1363
 
1364
+ let clamped = 0;
1365
+
425
1366
  const storage = system.storage;
426
- const count = storage.awake_count;
1367
+ const count = captured < storage.awake_count ? captured : storage.awake_count;
427
1368
  const lists = system.__body_collider_lists;
428
1369
  const start = system.__ccd_start_pos;
1370
+ const gravity = system.gravity;
429
1371
  const CCD = RigidBodyFlags.CCD;
430
1372
 
431
- // Collect the CCD-eligible awake bodies…
1373
+ // Collect the movers the step took a start pose for (`__ccd_movers`), as
1374
+ // they still are: awake, dynamic, flagged, and swept by the same primary
1375
+ // collider. A body woken, flagged or given its first collider since — by
1376
+ // a listener on an announcement, say — has no start pose this step: its
1377
+ // slot held whatever was there, the origin for a body never swept, and a
1378
+ // ball 5 m out was swept from the origin and clamped 2.65 m back at a wall
1379
+ // half way…
1380
+ const movers = system.__ccd_movers;
1381
+ const mover_colliders = system.__ccd_mover_colliders;
1382
+ const mover_count = system.__ccd_mover_count;
432
1383
  let n = 0;
433
- for (let i = 0; i < count; i++) {
434
- const idx = storage.awake_at(i);
1384
+ for (let k = 0; k < mover_count; k++) {
1385
+ const idx = movers[k];
1386
+ if (!storage.is_awake(idx)) continue;
435
1387
 
436
1388
  const rb = system.__bodies[idx];
437
1389
  if (rb === undefined) continue;
@@ -439,7 +1391,7 @@ export function ccd_resolve(system) {
439
1391
  if (rb.kind !== BodyKind.Dynamic) continue;
440
1392
 
441
1393
  const list = lists[idx];
442
- if (list === undefined || list.length === 0) continue;
1394
+ if (list === undefined || list.length === 0 || list[0].collider !== mover_colliders[k]) continue;
443
1395
 
444
1396
  if (n === _ccd_order.length) {
445
1397
  const next = new Uint32Array(_ccd_order.length * 2);
@@ -448,7 +1400,24 @@ export function ccd_resolve(system) {
448
1400
  }
449
1401
  _ccd_order[n++] = idx;
450
1402
  }
451
- if (n === 0) return;
1403
+ if (n === 0) return 0;
1404
+
1405
+ // Each awake dynamic body's velocity change through the solve, in place of
1406
+ // its start-of-step velocity, read now: before this pass's own impulses
1407
+ // change any of them. See {@link blocker_fall}.
1408
+ const change = system.__ccd_start_vel;
1409
+ for (let i = 0; i < count; i++) {
1410
+ const idx = storage.awake_at(i);
1411
+
1412
+ const rb = system.__bodies[idx];
1413
+ if (rb === undefined || rb.kind !== BodyKind.Dynamic) continue;
1414
+
1415
+ const lv = rb.linearVelocity;
1416
+ const b = idx * 3;
1417
+ change[b] = lv[0] - change[b];
1418
+ change[b + 1] = lv[1] - change[b + 1];
1419
+ change[b + 2] = lv[2] - change[b + 2];
1420
+ }
452
1421
 
453
1422
  // …and order them by entity (insertion sort; CCD bodies are few).
454
1423
  for (let i = 1; i < n; i++) {
@@ -468,15 +1437,14 @@ export function ccd_resolve(system) {
468
1437
  const list = lists[idx];
469
1438
  const primary = list[0];
470
1439
  const tr = primary.transform;
471
- const p = tr.translation;
472
1440
 
473
1441
  const base = idx * 3;
474
1442
  const sx = start[base];
475
1443
  const sy = start[base + 1];
476
1444
  const sz = start[base + 2];
477
- const ex = p[0];
478
- const ey = p[1];
479
- const ez = p[2];
1445
+ const ex = tr.translation_x;
1446
+ const ey = tr.translation_y;
1447
+ const ez = tr.translation_z;
480
1448
 
481
1449
  const dx = ex - sx;
482
1450
  const dy = ey - sy;
@@ -497,56 +1465,122 @@ export function ccd_resolve(system) {
497
1465
  // NOT primary.entity: a compound body's primary collider can live on a
498
1466
  // CHILD entity, and excluding that child would leave the body's other
499
1467
  // leaves visible to its own sweep (self-hit at t = 0).
500
- const frac = ccd_sweep_segment(
501
- system, shape, tr.rotation,
1468
+ const entity = storage.entity_at(idx);
1469
+
1470
+ _sweep_rotation[0] = tr.rotation_x;
1471
+ _sweep_rotation[1] = tr.rotation_y;
1472
+ _sweep_rotation[2] = tr.rotation_z;
1473
+ _sweep_rotation[3] = tr.rotation_w;
1474
+
1475
+ let frac = ccd_sweep_segment(
1476
+ system, shape, _sweep_rotation,
502
1477
  sx, sy, sz, ex, ey, ez,
503
- storage.entity_at(idx), _hit,
1478
+ entity, _hit,
504
1479
  );
1480
+
1481
+ // A convex collider the body starts the step touching and slides
1482
+ // along is in a contact for the next discrete step to resolve, not a
1483
+ // tunnel: the sweep steps past THAT collider and sweeps again, for
1484
+ // whatever else is in the way. See {@link CCD_CONTACT_SLOP}.
1485
+ while (frac < 1 && step_past_slid_along(system, _hit, shape, tr, sx, sy, sz, ex, ey, ez)) {
1486
+ frac = ccd_sweep_segment(
1487
+ system, shape, _sweep_rotation,
1488
+ sx, sy, sz, ex, ey, ez,
1489
+ entity, _hit,
1490
+ );
1491
+ }
1492
+ clear_slid_along();
1493
+
505
1494
  if (frac >= 1) continue; // clear path — no tunnelling this step
506
1495
 
1496
+ const hp = _hit.position;
1497
+ const cdx = hp[0] - ex;
1498
+ const cdy = hp[1] - ey;
1499
+ const cdz = hp[2] - ez;
1500
+ const n_hit = _hit.normal;
1501
+
507
1502
  // Clamp the body to the first-contact pose (swept-shape centre at the
508
1503
  // TOI), so it cannot end the step on the far side of the blocker.
509
1504
  //
510
1505
  // The sweep is of the primary COLLIDER, whose transform is the body's
511
1506
  // own only for a same-entity collider. The clamp has to land on the
512
- // body — that is what integration moved and what the velocity fix
513
- // below applies to — so a child collider's transform is displaced by
1507
+ // body — that is what integration moved and what the response below
1508
+ // applies to — so a child collider's transform is displaced by
514
1509
  // the same delta rather than being assigned the swept centre, which
515
1510
  // would move the child out from under the body it belongs to.
516
- const hp = _hit.position;
517
1511
  const body_tr = system.__transforms[idx];
518
- if (body_tr === tr) {
519
- p[0] = hp[0];
520
- p[1] = hp[1];
521
- p[2] = hp[2];
522
- } else {
523
- const bp = body_tr.translation;
524
- bp[0] += hp[0] - ex;
525
- bp[1] += hp[1] - ey;
526
- bp[2] += hp[2] - ez;
527
- p[0] = hp[0];
528
- p[1] = hp[1];
529
- p[2] = hp[2];
1512
+ if (body_tr !== tr) {
1513
+ body_tr.setTranslation(
1514
+ body_tr.translation_x + cdx,
1515
+ body_tr.translation_y + cdy,
1516
+ body_tr.translation_z + cdz
1517
+ );
530
1518
  }
1519
+ tr.setTranslation(hp[0], hp[1], hp[2]);
531
1520
 
532
- // Remove the inbound normal component of velocity (inelastic stop).
533
- // `_hit.normal` is the blocker's outward surface normal; the body is
534
- // moving into it (v·n < 0). Zeroing that component leaves the tangential
535
- // slide intact and never adds energy. The next discrete step applies the
536
- // real restitution / friction on the established contact.
537
- const n = _hit.normal;
538
- const lv = rb.linearVelocity;
539
- const vn = lv[0] * n[0] + lv[1] * n[1] + lv[2] * n[2];
540
- if (vn < 0) {
541
- lv[0] -= vn * n[0];
542
- lv[1] -= vn * n[1];
543
- lv[2] -= vn * n[2];
1521
+ // The body's OTHER child-entity colliders go with it too. They are
1522
+ // re-composed only when the body is announced again, after this pass,
1523
+ // and a CCD body swept later in this pass would meet them where the
1524
+ // body would have tunnelled to: a ball falling past a clamped body's
1525
+ // child collider, 0.1 to its side, swept against the child 0.1 further
1526
+ // off and ended the step 10 cm inside it. The clamp is a translation,
1527
+ // so every child moves by the same delta.
1528
+ for (let c = 1; c < list.length; c++) {
1529
+ const ct = list[c].transform;
1530
+ if (ct === body_tr || ct === tr) continue;
1531
+ let seen = false;
1532
+ for (let o = 1; o < c; o++) {
1533
+ if (list[o].transform === ct) { seen = true; break; }
1534
+ }
1535
+ if (seen) continue;
1536
+ ct.setTranslation(ct.translation_x + cdx, ct.translation_y + cdy, ct.translation_z + cdz);
1537
+ }
1538
+
1539
+ if (clamped === _clamped_bodies.length) {
1540
+ const next = new Uint32Array(_clamped_bodies.length * 2);
1541
+ next.set(_clamped_bodies);
1542
+ _clamped_bodies = next;
544
1543
  }
1544
+ _clamped_bodies[clamped++] = idx;
1545
+
1546
+ // The body is now where it was at the moment of impact, so its velocity
1547
+ // must not carry the gravity of the rest of the step, which it never
1548
+ // travelled. See {@link ccd_velocity_at_impact}; the struck body's fall
1549
+ // ({@link blocker_fall}) only sets the relative integrator lag.
1550
+ ccd_velocity_at_impact(
1551
+ rb.linearVelocity,
1552
+ gravity[0] * rb.gravityScale, gravity[1] * rb.gravityScale, gravity[2] * rb.gravityScale,
1553
+ blocker_fall(system, _hit, dt, captured),
1554
+ hp[0] - sx, hp[1] - sy, hp[2] - sz,
1555
+ n_hit, frac, dt, h
1556
+ );
1557
+
1558
+ // Answer the impact where it happened: the pair's restitution, and an
1559
+ // impulse shared with a dynamic blocker. Nothing later will — the body
1560
+ // now rests at the surface without penetrating it (clear of a convex,
1561
+ // on a triangle's face to rounding), where the narrowphase sees no
1562
+ // contact. See {@link ccd_respond}.
1563
+ ccd_contact(system, primary.collider, tr, _hit);
1564
+ ccd_respond(system, rb, body_tr, _hit);
545
1565
 
546
1566
  // Tell the world it happened. The clamp above is the whole of the
547
1567
  // collision — the discrete narrowphase samples step boundaries and this
548
1568
  // impact was between two of them — so without this the body is stopped
549
1569
  // dead and nothing is ever told. See {@link record_ccd_contact}.
550
- record_ccd_contact(system, idx, primary.collider, tr, _hit);
1570
+ record_ccd_contact(system, idx, _hit);
551
1571
  }
1572
+
1573
+ return clamped;
1574
+ }
1575
+
1576
+ /**
1577
+ * Storage indices of the bodies the last {@link ccd_resolve} clamped; the
1578
+ * first `n` entries are live, `n` being what that call returned. The array is
1579
+ * the pass's own scratch: read it before the next pass, and do not keep it
1580
+ * (it is replaced when it grows).
1581
+ *
1582
+ * @returns {Uint32Array}
1583
+ */
1584
+ export function ccd_clamped_bodies() {
1585
+ return _clamped_bodies;
552
1586
  }