@adobe/data-gpu 0.9.69

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 (584) hide show
  1. package/CLAUDE.md +98 -0
  2. package/LICENSE +21 -0
  3. package/dist/core/core-plugin.d.ts +44 -0
  4. package/dist/core/core-plugin.js +90 -0
  5. package/dist/core/core-plugin.js.map +1 -0
  6. package/dist/core/frame-time/frame-time-plugin.d.ts +25 -0
  7. package/dist/core/frame-time/frame-time-plugin.js +41 -0
  8. package/dist/core/frame-time/frame-time-plugin.js.map +1 -0
  9. package/dist/core/frame-time/frame-time.d.ts +18 -0
  10. package/dist/core/frame-time/frame-time.js +3 -0
  11. package/dist/core/frame-time/frame-time.js.map +1 -0
  12. package/dist/core/frame-time/public.d.ts +1 -0
  13. package/dist/core/frame-time/public.js +3 -0
  14. package/dist/core/frame-time/public.js.map +1 -0
  15. package/dist/graphics/animation/animation-data-plugin.d.ts +216 -0
  16. package/dist/graphics/animation/animation-data-plugin.js +110 -0
  17. package/dist/graphics/animation/animation-data-plugin.js.map +1 -0
  18. package/dist/graphics/animation/animation-plugin.d.ts +214 -0
  19. package/dist/graphics/animation/animation-plugin.js +26 -0
  20. package/dist/graphics/animation/animation-plugin.js.map +1 -0
  21. package/dist/graphics/animation/animation-plugin.test.d.ts +1 -0
  22. package/dist/graphics/animation/animation-plugin.test.js +142 -0
  23. package/dist/graphics/animation/animation-plugin.test.js.map +1 -0
  24. package/dist/graphics/animation/animation-track/animation-track.d.ts +13 -0
  25. package/dist/graphics/animation/animation-track/animation-track.js +3 -0
  26. package/dist/graphics/animation/animation-track/animation-track.js.map +1 -0
  27. package/dist/graphics/animation/animation-track/componentwise-lerp.d.ts +7 -0
  28. package/dist/graphics/animation/animation-track/componentwise-lerp.js +22 -0
  29. package/dist/graphics/animation/animation-track/componentwise-lerp.js.map +1 -0
  30. package/dist/graphics/animation/animation-track/interpolate.d.ts +8 -0
  31. package/dist/graphics/animation/animation-track/interpolate.js +18 -0
  32. package/dist/graphics/animation/animation-track/interpolate.js.map +1 -0
  33. package/dist/graphics/animation/animation-track/public.d.ts +1 -0
  34. package/dist/graphics/animation/animation-track/public.js +3 -0
  35. package/dist/graphics/animation/animation-track/public.js.map +1 -0
  36. package/dist/graphics/animation/animation-track/sample.d.ts +7 -0
  37. package/dist/graphics/animation/animation-track/sample.js +44 -0
  38. package/dist/graphics/animation/animation-track/sample.js.map +1 -0
  39. package/dist/graphics/animation/interpolation-mode/interpolation-mode.d.ts +4 -0
  40. package/dist/graphics/animation/interpolation-mode/interpolation-mode.js +3 -0
  41. package/dist/graphics/animation/interpolation-mode/interpolation-mode.js.map +1 -0
  42. package/dist/graphics/animation/interpolation-mode/public.d.ts +1 -0
  43. package/dist/graphics/animation/interpolation-mode/public.js +3 -0
  44. package/dist/graphics/animation/interpolation-mode/public.js.map +1 -0
  45. package/dist/graphics/animation/interpolation-mode/schema.d.ts +4 -0
  46. package/dist/graphics/animation/interpolation-mode/schema.js +3 -0
  47. package/dist/graphics/animation/interpolation-mode/schema.js.map +1 -0
  48. package/dist/graphics/camera/camera-plugin.d.ts +112 -0
  49. package/dist/graphics/camera/camera-plugin.js +36 -0
  50. package/dist/graphics/camera/camera-plugin.js.map +1 -0
  51. package/dist/graphics/camera/camera.d.ts +4 -0
  52. package/dist/graphics/camera/camera.js +3 -0
  53. package/dist/graphics/camera/camera.js.map +1 -0
  54. package/dist/graphics/camera/orbit/attach-orbit-drag.d.ts +31 -0
  55. package/dist/graphics/camera/orbit/attach-orbit-drag.js +44 -0
  56. package/dist/graphics/camera/orbit/attach-orbit-drag.js.map +1 -0
  57. package/dist/graphics/camera/orbit/orbit-data-plugin.d.ts +290 -0
  58. package/dist/graphics/camera/orbit/orbit-data-plugin.js +42 -0
  59. package/dist/graphics/camera/orbit/orbit-data-plugin.js.map +1 -0
  60. package/dist/graphics/camera/orbit/orbit-plugin.d.ts +281 -0
  61. package/dist/graphics/camera/orbit/orbit-plugin.js +12 -0
  62. package/dist/graphics/camera/orbit/orbit-plugin.js.map +1 -0
  63. package/dist/graphics/camera/orbit/orbit-system-plugin.d.ts +292 -0
  64. package/dist/graphics/camera/orbit/orbit-system-plugin.js +71 -0
  65. package/dist/graphics/camera/orbit/orbit-system-plugin.js.map +1 -0
  66. package/dist/graphics/camera/orbit/orbit.d.ts +32 -0
  67. package/dist/graphics/camera/orbit/orbit.js +3 -0
  68. package/dist/graphics/camera/orbit/orbit.js.map +1 -0
  69. package/dist/graphics/camera/orbit/public.d.ts +5 -0
  70. package/dist/graphics/camera/orbit/public.js +6 -0
  71. package/dist/graphics/camera/orbit/public.js.map +1 -0
  72. package/dist/graphics/camera/public.d.ts +4 -0
  73. package/dist/graphics/camera/public.js +6 -0
  74. package/dist/graphics/camera/public.js.map +1 -0
  75. package/dist/graphics/camera/schema.d.ts +65 -0
  76. package/dist/graphics/camera/schema.js +19 -0
  77. package/dist/graphics/camera/schema.js.map +1 -0
  78. package/dist/graphics/camera/screen-to-world-ray.d.ts +10 -0
  79. package/dist/graphics/camera/screen-to-world-ray.js +31 -0
  80. package/dist/graphics/camera/screen-to-world-ray.js.map +1 -0
  81. package/dist/graphics/camera/to-view-projection.d.ts +3 -0
  82. package/dist/graphics/camera/to-view-projection.js +23 -0
  83. package/dist/graphics/camera/to-view-projection.js.map +1 -0
  84. package/dist/graphics/graphics-plugin.d.ts +121 -0
  85. package/dist/graphics/graphics-plugin.js +106 -0
  86. package/dist/graphics/graphics-plugin.js.map +1 -0
  87. package/dist/graphics/picking/pick-hit.d.ts +10 -0
  88. package/dist/graphics/picking/pick-hit.js +3 -0
  89. package/dist/graphics/picking/pick-hit.js.map +1 -0
  90. package/dist/graphics/picking/picking-plugin.d.ts +3819 -0
  91. package/dist/graphics/picking/picking-plugin.js +88 -0
  92. package/dist/graphics/picking/picking-plugin.js.map +1 -0
  93. package/dist/graphics/rendering/bone-collider-plugin.d.ts +1619 -0
  94. package/dist/graphics/rendering/bone-collider-plugin.js +207 -0
  95. package/dist/graphics/rendering/bone-collider-plugin.js.map +1 -0
  96. package/dist/graphics/rendering/display-transform-plugin.d.ts +52 -0
  97. package/dist/graphics/rendering/display-transform-plugin.js +25 -0
  98. package/dist/graphics/rendering/display-transform-plugin.js.map +1 -0
  99. package/dist/graphics/rendering/ibl-render/brdf.wgsl.d.ts +2 -0
  100. package/dist/graphics/rendering/ibl-render/brdf.wgsl.js +42 -0
  101. package/dist/graphics/rendering/ibl-render/brdf.wgsl.js.map +1 -0
  102. package/dist/graphics/rendering/ibl-render/ibl/brdf-lut.d.ts +1 -0
  103. package/dist/graphics/rendering/ibl-render/ibl/brdf-lut.js +91 -0
  104. package/dist/graphics/rendering/ibl-render/ibl/brdf-lut.js.map +1 -0
  105. package/dist/graphics/rendering/ibl-render/ibl/build-ibl-resources.d.ts +24 -0
  106. package/dist/graphics/rendering/ibl-render/ibl/build-ibl-resources.js +34 -0
  107. package/dist/graphics/rendering/ibl-render/ibl/build-ibl-resources.js.map +1 -0
  108. package/dist/graphics/rendering/ibl-render/ibl/create-cubemap.d.ts +1 -0
  109. package/dist/graphics/rendering/ibl-render/ibl/create-cubemap.js +12 -0
  110. package/dist/graphics/rendering/ibl-render/ibl/create-cubemap.js.map +1 -0
  111. package/dist/graphics/rendering/ibl-render/ibl/cube-face-view.d.ts +1 -0
  112. package/dist/graphics/rendering/ibl-render/ibl/cube-face-view.js +11 -0
  113. package/dist/graphics/rendering/ibl-render/ibl/cube-face-view.js.map +1 -0
  114. package/dist/graphics/rendering/ibl-render/ibl/cubemap-sample-view.d.ts +1 -0
  115. package/dist/graphics/rendering/ibl-render/ibl/cubemap-sample-view.js +9 -0
  116. package/dist/graphics/rendering/ibl-render/ibl/cubemap-sample-view.js.map +1 -0
  117. package/dist/graphics/rendering/ibl-render/ibl/environment.d.ts +8 -0
  118. package/dist/graphics/rendering/ibl-render/ibl/environment.js +170 -0
  119. package/dist/graphics/rendering/ibl-render/ibl/environment.js.map +1 -0
  120. package/dist/graphics/rendering/ibl-render/ibl/float-to-half.d.ts +2 -0
  121. package/dist/graphics/rendering/ibl-render/ibl/float-to-half.js +32 -0
  122. package/dist/graphics/rendering/ibl-render/ibl/float-to-half.js.map +1 -0
  123. package/dist/graphics/rendering/ibl-render/ibl/ibl-math.wgsl.d.ts +2 -0
  124. package/dist/graphics/rendering/ibl-render/ibl/ibl-math.wgsl.js +59 -0
  125. package/dist/graphics/rendering/ibl-render/ibl/ibl-math.wgsl.js.map +1 -0
  126. package/dist/graphics/rendering/ibl-render/ibl/irradiance.d.ts +1 -0
  127. package/dist/graphics/rendering/ibl-render/ibl/irradiance.js +94 -0
  128. package/dist/graphics/rendering/ibl-render/ibl/irradiance.js.map +1 -0
  129. package/dist/graphics/rendering/ibl-render/ibl/parse-hdr.d.ts +6 -0
  130. package/dist/graphics/rendering/ibl-render/ibl/parse-hdr.js +106 -0
  131. package/dist/graphics/rendering/ibl-render/ibl/parse-hdr.js.map +1 -0
  132. package/dist/graphics/rendering/ibl-render/ibl/prefilter.d.ts +5 -0
  133. package/dist/graphics/rendering/ibl-render/ibl/prefilter.js +103 -0
  134. package/dist/graphics/rendering/ibl-render/ibl/prefilter.js.map +1 -0
  135. package/dist/graphics/rendering/ibl-render/ibl/render-helpers.d.ts +4 -0
  136. package/dist/graphics/rendering/ibl-render/ibl/render-helpers.js +16 -0
  137. package/dist/graphics/rendering/ibl-render/ibl/render-helpers.js.map +1 -0
  138. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.d.ts +1028 -0
  139. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.js +409 -0
  140. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.js.map +1 -0
  141. package/dist/graphics/rendering/ibl-render/ibl-shader.wgsl.d.ts +8 -0
  142. package/dist/graphics/rendering/ibl-render/ibl-shader.wgsl.js +173 -0
  143. package/dist/graphics/rendering/ibl-render/ibl-shader.wgsl.js.map +1 -0
  144. package/dist/graphics/rendering/ibl-render/skybox-shader.wgsl.d.ts +2 -0
  145. package/dist/graphics/rendering/ibl-render/skybox-shader.wgsl.js +50 -0
  146. package/dist/graphics/rendering/ibl-render/skybox-shader.wgsl.js.map +1 -0
  147. package/dist/graphics/rendering/interpolation-plugin.d.ts +485 -0
  148. package/dist/graphics/rendering/interpolation-plugin.js +98 -0
  149. package/dist/graphics/rendering/interpolation-plugin.js.map +1 -0
  150. package/dist/graphics/rendering/interpolation.test.d.ts +1 -0
  151. package/dist/graphics/rendering/interpolation.test.js +38 -0
  152. package/dist/graphics/rendering/interpolation.test.js.map +1 -0
  153. package/dist/graphics/rendering/jolt-ragdoll-plugin.d.ts +1628 -0
  154. package/dist/graphics/rendering/jolt-ragdoll-plugin.js +218 -0
  155. package/dist/graphics/rendering/jolt-ragdoll-plugin.js.map +1 -0
  156. package/dist/graphics/rendering/material-gpu/material-arrays.d.ts +47 -0
  157. package/dist/graphics/rendering/material-gpu/material-arrays.js +83 -0
  158. package/dist/graphics/rendering/material-gpu/material-arrays.js.map +1 -0
  159. package/dist/graphics/rendering/material-gpu/material-bind-group.d.ts +9 -0
  160. package/dist/graphics/rendering/material-gpu/material-bind-group.js +52 -0
  161. package/dist/graphics/rendering/material-gpu/material-bind-group.js.map +1 -0
  162. package/dist/graphics/rendering/material-gpu/material-gpu-plugin.d.ts +259 -0
  163. package/dist/graphics/rendering/material-gpu/material-gpu-plugin.js +90 -0
  164. package/dist/graphics/rendering/material-gpu/material-gpu-plugin.js.map +1 -0
  165. package/dist/graphics/rendering/model-collider-plugin.d.ts +1232 -0
  166. package/dist/graphics/rendering/model-collider-plugin.js +81 -0
  167. package/dist/graphics/rendering/model-collider-plugin.js.map +1 -0
  168. package/dist/graphics/rendering/pbr-core-plugin.d.ts +75 -0
  169. package/dist/graphics/rendering/pbr-core-plugin.js +39 -0
  170. package/dist/graphics/rendering/pbr-core-plugin.js.map +1 -0
  171. package/dist/graphics/rendering/pbr-render/pbr-array-shader.wgsl.d.ts +10 -0
  172. package/dist/graphics/rendering/pbr-render/pbr-array-shader.wgsl.js +145 -0
  173. package/dist/graphics/rendering/pbr-render/pbr-array-shader.wgsl.js.map +1 -0
  174. package/dist/graphics/rendering/pbr-render/pbr-render-plugin.d.ts +1266 -0
  175. package/dist/graphics/rendering/pbr-render/pbr-render-plugin.js +254 -0
  176. package/dist/graphics/rendering/pbr-render/pbr-render-plugin.js.map +1 -0
  177. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.d.ts +1004 -0
  178. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.js +116 -0
  179. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.js.map +1 -0
  180. package/dist/graphics/rendering/ragdoll-trigger-plugin.d.ts +31 -0
  181. package/dist/graphics/rendering/ragdoll-trigger-plugin.js +20 -0
  182. package/dist/graphics/rendering/ragdoll-trigger-plugin.js.map +1 -0
  183. package/dist/graphics/rendering/rendering-plugin.d.ts +1 -0
  184. package/dist/graphics/rendering/rendering-plugin.js +3 -0
  185. package/dist/graphics/rendering/rendering-plugin.js.map +1 -0
  186. package/dist/graphics/rendering/skinning/skinning-attributes/layout.d.ts +2 -0
  187. package/dist/graphics/rendering/skinning/skinning-attributes/layout.js +18 -0
  188. package/dist/graphics/rendering/skinning/skinning-attributes/layout.js.map +1 -0
  189. package/dist/graphics/rendering/skinning/skinning-attributes/public.d.ts +1 -0
  190. package/dist/graphics/rendering/skinning/skinning-attributes/public.js +3 -0
  191. package/dist/graphics/rendering/skinning/skinning-attributes/public.js.map +1 -0
  192. package/dist/graphics/rendering/skinning/skinning-attributes/skinning-attributes.d.ts +1 -0
  193. package/dist/graphics/rendering/skinning/skinning-attributes/skinning-attributes.js +3 -0
  194. package/dist/graphics/rendering/skinning/skinning-attributes/skinning-attributes.js.map +1 -0
  195. package/dist/graphics/rendering/skinning/skinning-plugin.d.ts +1212 -0
  196. package/dist/graphics/rendering/skinning/skinning-plugin.js +207 -0
  197. package/dist/graphics/rendering/skinning/skinning-plugin.js.map +1 -0
  198. package/dist/graphics/rendering/standard-vertex/layout.d.ts +2 -0
  199. package/dist/graphics/rendering/standard-vertex/layout.js +16 -0
  200. package/dist/graphics/rendering/standard-vertex/layout.js.map +1 -0
  201. package/dist/graphics/rendering/standard-vertex/public.d.ts +2 -0
  202. package/dist/graphics/rendering/standard-vertex/public.js +4 -0
  203. package/dist/graphics/rendering/standard-vertex/public.js.map +1 -0
  204. package/dist/graphics/rendering/standard-vertex/schema.d.ts +52 -0
  205. package/dist/graphics/rendering/standard-vertex/schema.js +15 -0
  206. package/dist/graphics/rendering/standard-vertex/schema.js.map +1 -0
  207. package/dist/graphics/rendering/standard-vertex/standard-vertex.d.ts +4 -0
  208. package/dist/graphics/rendering/standard-vertex/standard-vertex.js +3 -0
  209. package/dist/graphics/rendering/standard-vertex/standard-vertex.js.map +1 -0
  210. package/dist/graphics/rendering/visible-material/color-material-options.d.ts +7 -0
  211. package/dist/graphics/rendering/visible-material/color-material-options.js +3 -0
  212. package/dist/graphics/rendering/visible-material/color-material-options.js.map +1 -0
  213. package/dist/graphics/rendering/visible-material/create-bind-group-layout.d.ts +8 -0
  214. package/dist/graphics/rendering/visible-material/create-bind-group-layout.js +35 -0
  215. package/dist/graphics/rendering/visible-material/create-bind-group-layout.js.map +1 -0
  216. package/dist/graphics/rendering/visible-material/create-color-bind-group.d.ts +10 -0
  217. package/dist/graphics/rendering/visible-material/create-color-bind-group.js +26 -0
  218. package/dist/graphics/rendering/visible-material/create-color-bind-group.js.map +1 -0
  219. package/dist/graphics/rendering/visible-material/public.d.ts +4 -0
  220. package/dist/graphics/rendering/visible-material/public.js +5 -0
  221. package/dist/graphics/rendering/visible-material/public.js.map +1 -0
  222. package/dist/graphics/rendering/visible-material/schema.d.ts +49 -0
  223. package/dist/graphics/rendering/visible-material/schema.js +23 -0
  224. package/dist/graphics/rendering/visible-material/schema.js.map +1 -0
  225. package/dist/graphics/rendering/visible-material/visible-material.d.ts +4 -0
  226. package/dist/graphics/rendering/visible-material/visible-material.js +3 -0
  227. package/dist/graphics/rendering/visible-material/visible-material.js.map +1 -0
  228. package/dist/graphics/scene/light/light-plugin.d.ts +30 -0
  229. package/dist/graphics/scene/light/light-plugin.js +35 -0
  230. package/dist/graphics/scene/light/light-plugin.js.map +1 -0
  231. package/dist/graphics/scene/light/light.d.ts +14 -0
  232. package/dist/graphics/scene/light/light.js +3 -0
  233. package/dist/graphics/scene/light/light.js.map +1 -0
  234. package/dist/graphics/scene/light/public.d.ts +1 -0
  235. package/dist/graphics/scene/light/public.js +2 -0
  236. package/dist/graphics/scene/light/public.js.map +1 -0
  237. package/dist/graphics/scene/model/geometry/geometry.d.ts +9 -0
  238. package/dist/graphics/scene/model/geometry/geometry.js +3 -0
  239. package/dist/graphics/scene/model/geometry/geometry.js.map +1 -0
  240. package/dist/graphics/scene/model/geometry/public.d.ts +1 -0
  241. package/dist/graphics/scene/model/geometry/public.js +3 -0
  242. package/dist/graphics/scene/model/geometry/public.js.map +1 -0
  243. package/dist/graphics/scene/model/gltf/accessor-view.d.ts +9 -0
  244. package/dist/graphics/scene/model/gltf/accessor-view.js +44 -0
  245. package/dist/graphics/scene/model/gltf/accessor-view.js.map +1 -0
  246. package/dist/graphics/scene/model/gltf/build-material-bind-group.d.ts +22 -0
  247. package/dist/graphics/scene/model/gltf/build-material-bind-group.js +75 -0
  248. package/dist/graphics/scene/model/gltf/build-material-bind-group.js.map +1 -0
  249. package/dist/graphics/scene/model/gltf/compute-world-matrices.d.ts +7 -0
  250. package/dist/graphics/scene/model/gltf/compute-world-matrices.js +38 -0
  251. package/dist/graphics/scene/model/gltf/compute-world-matrices.js.map +1 -0
  252. package/dist/graphics/scene/model/gltf/create-color-material.d.ts +3 -0
  253. package/dist/graphics/scene/model/gltf/create-color-material.js +34 -0
  254. package/dist/graphics/scene/model/gltf/create-color-material.js.map +1 -0
  255. package/dist/graphics/scene/model/gltf/decode-images.d.ts +12 -0
  256. package/dist/graphics/scene/model/gltf/decode-images.js +68 -0
  257. package/dist/graphics/scene/model/gltf/decode-images.js.map +1 -0
  258. package/dist/graphics/scene/model/gltf/gltf-schema.d.ts +152 -0
  259. package/dist/graphics/scene/model/gltf/gltf-schema.js +20 -0
  260. package/dist/graphics/scene/model/gltf/gltf-schema.js.map +1 -0
  261. package/dist/graphics/scene/model/gltf/load-gltf-model.d.ts +42 -0
  262. package/dist/graphics/scene/model/gltf/load-gltf-model.js +175 -0
  263. package/dist/graphics/scene/model/gltf/load-gltf-model.js.map +1 -0
  264. package/dist/graphics/scene/model/gltf/pack-vertex-buffer.d.ts +21 -0
  265. package/dist/graphics/scene/model/gltf/pack-vertex-buffer.js +106 -0
  266. package/dist/graphics/scene/model/gltf/pack-vertex-buffer.js.map +1 -0
  267. package/dist/graphics/scene/model/gltf/parse-animations.d.ts +18 -0
  268. package/dist/graphics/scene/model/gltf/parse-animations.js +51 -0
  269. package/dist/graphics/scene/model/gltf/parse-animations.js.map +1 -0
  270. package/dist/graphics/scene/model/gltf/parse-glb.d.ts +6 -0
  271. package/dist/graphics/scene/model/gltf/parse-glb.js +40 -0
  272. package/dist/graphics/scene/model/gltf/parse-glb.js.map +1 -0
  273. package/dist/graphics/scene/model/gltf/parse-skin.d.ts +19 -0
  274. package/dist/graphics/scene/model/gltf/parse-skin.js +43 -0
  275. package/dist/graphics/scene/model/gltf/parse-skin.js.map +1 -0
  276. package/dist/graphics/scene/model/model-loader-plugin.d.ts +922 -0
  277. package/dist/graphics/scene/model/model-loader-plugin.js +120 -0
  278. package/dist/graphics/scene/model/model-loader-plugin.js.map +1 -0
  279. package/dist/graphics/scene/model/model-plugin.d.ts +352 -0
  280. package/dist/graphics/scene/model/model-plugin.js +39 -0
  281. package/dist/graphics/scene/model/model-plugin.js.map +1 -0
  282. package/dist/graphics/scene/model/model.d.ts +11 -0
  283. package/dist/graphics/scene/model/model.js +3 -0
  284. package/dist/graphics/scene/model/model.js.map +1 -0
  285. package/dist/graphics/scene/model/public.d.ts +1 -0
  286. package/dist/graphics/scene/model/public.js +2 -0
  287. package/dist/graphics/scene/model/public.js.map +1 -0
  288. package/dist/graphics/scene/model/shape/convex-hull.d.ts +36 -0
  289. package/dist/graphics/scene/model/shape/convex-hull.js +152 -0
  290. package/dist/graphics/scene/model/shape/convex-hull.js.map +1 -0
  291. package/dist/graphics/scene/model/shape/convex-hull.test.d.ts +1 -0
  292. package/dist/graphics/scene/model/shape/convex-hull.test.js +78 -0
  293. package/dist/graphics/scene/model/shape/convex-hull.test.js.map +1 -0
  294. package/dist/graphics/scene/model/shape/shape-geometry-plugin.d.ts +631 -0
  295. package/dist/graphics/scene/model/shape/shape-geometry-plugin.js +61 -0
  296. package/dist/graphics/scene/model/shape/shape-geometry-plugin.js.map +1 -0
  297. package/dist/graphics/scene/model/shape/shape-mesh.d.ts +34 -0
  298. package/dist/graphics/scene/model/shape/shape-mesh.js +142 -0
  299. package/dist/graphics/scene/model/shape/shape-mesh.js.map +1 -0
  300. package/dist/graphics/scene/model/shape/upload-shape-mesh.d.ts +9 -0
  301. package/dist/graphics/scene/model/shape/upload-shape-mesh.js +12 -0
  302. package/dist/graphics/scene/model/shape/upload-shape-mesh.js.map +1 -0
  303. package/dist/graphics/scene/model/world-bounds-plugin.d.ts +909 -0
  304. package/dist/graphics/scene/model/world-bounds-plugin.js +93 -0
  305. package/dist/graphics/scene/model/world-bounds-plugin.js.map +1 -0
  306. package/dist/graphics/scene/node/node-data-plugin.d.ts +113 -0
  307. package/dist/graphics/scene/node/node-data-plugin.js +27 -0
  308. package/dist/graphics/scene/node/node-data-plugin.js.map +1 -0
  309. package/dist/graphics/scene/node/node-plugin.d.ts +102 -0
  310. package/dist/graphics/scene/node/node-plugin.js +12 -0
  311. package/dist/graphics/scene/node/node-plugin.js.map +1 -0
  312. package/dist/graphics/scene/node/node.d.ts +19 -0
  313. package/dist/graphics/scene/node/node.js +3 -0
  314. package/dist/graphics/scene/node/node.js.map +1 -0
  315. package/dist/graphics/scene/node/public.d.ts +1 -0
  316. package/dist/graphics/scene/node/public.js +2 -0
  317. package/dist/graphics/scene/node/public.js.map +1 -0
  318. package/dist/graphics/scene/node/transform-plugin.d.ts +123 -0
  319. package/dist/graphics/scene/node/transform-plugin.js +65 -0
  320. package/dist/graphics/scene/node/transform-plugin.js.map +1 -0
  321. package/dist/graphics/scene/scene-plugin.d.ts +461 -0
  322. package/dist/graphics/scene/scene-plugin.js +19 -0
  323. package/dist/graphics/scene/scene-plugin.js.map +1 -0
  324. package/dist/graphics/scene/scene-uniforms/create-bind-group-layout.d.ts +7 -0
  325. package/dist/graphics/scene/scene-uniforms/create-bind-group-layout.js +19 -0
  326. package/dist/graphics/scene/scene-uniforms/create-bind-group-layout.js.map +1 -0
  327. package/dist/graphics/scene/scene-uniforms/public.d.ts +3 -0
  328. package/dist/graphics/scene/scene-uniforms/public.js +5 -0
  329. package/dist/graphics/scene/scene-uniforms/public.js.map +1 -0
  330. package/dist/graphics/scene/scene-uniforms/scene-uniforms-plugin.d.ts +137 -0
  331. package/dist/graphics/scene/scene-uniforms/scene-uniforms-plugin.js +59 -0
  332. package/dist/graphics/scene/scene-uniforms/scene-uniforms-plugin.js.map +1 -0
  333. package/dist/graphics/scene/scene-uniforms/scene-uniforms.d.ts +11 -0
  334. package/dist/graphics/scene/scene-uniforms/scene-uniforms.js +3 -0
  335. package/dist/graphics/scene/scene-uniforms/scene-uniforms.js.map +1 -0
  336. package/dist/graphics/scene/scene-uniforms/schema.d.ts +56 -0
  337. package/dist/graphics/scene/scene-uniforms/schema.js +15 -0
  338. package/dist/graphics/scene/scene-uniforms/schema.js.map +1 -0
  339. package/dist/index.d.ts +53 -0
  340. package/dist/index.js +56 -0
  341. package/dist/index.js.map +1 -0
  342. package/dist/material/material-plugin.d.ts +221 -0
  343. package/dist/material/material-plugin.js +60 -0
  344. package/dist/material/material-plugin.js.map +1 -0
  345. package/dist/material/material.d.ts +31 -0
  346. package/dist/material/material.js +3 -0
  347. package/dist/material/material.js.map +1 -0
  348. package/dist/material/public.d.ts +2 -0
  349. package/dist/material/public.js +4 -0
  350. package/dist/material/public.js.map +1 -0
  351. package/dist/material/standard-materials.d.ts +3 -0
  352. package/dist/material/standard-materials.js +35 -0
  353. package/dist/material/standard-materials.js.map +1 -0
  354. package/dist/physics/body/body-type/body-type.d.ts +10 -0
  355. package/dist/physics/body/body-type/body-type.js +3 -0
  356. package/dist/physics/body/body-type/body-type.js.map +1 -0
  357. package/dist/physics/body/body-type/is-dynamic.d.ts +3 -0
  358. package/dist/physics/body/body-type/is-dynamic.js +6 -0
  359. package/dist/physics/body/body-type/is-dynamic.js.map +1 -0
  360. package/dist/physics/body/body-type/public.d.ts +2 -0
  361. package/dist/physics/body/body-type/public.js +4 -0
  362. package/dist/physics/body/body-type/public.js.map +1 -0
  363. package/dist/physics/body/body-type/schema.d.ts +4 -0
  364. package/dist/physics/body/body-type/schema.js +3 -0
  365. package/dist/physics/body/body-type/schema.js.map +1 -0
  366. package/dist/physics/body/collider-mesh.d.ts +11 -0
  367. package/dist/physics/body/collider-mesh.js +3 -0
  368. package/dist/physics/body/collider-mesh.js.map +1 -0
  369. package/dist/physics/body/collider-shape/collider-shape.d.ts +15 -0
  370. package/dist/physics/body/collider-shape/collider-shape.js +3 -0
  371. package/dist/physics/body/collider-shape/collider-shape.js.map +1 -0
  372. package/dist/physics/body/collider-shape/list.d.ts +3 -0
  373. package/dist/physics/body/collider-shape/list.js +5 -0
  374. package/dist/physics/body/collider-shape/list.js.map +1 -0
  375. package/dist/physics/body/collider-shape/mass-properties.d.ts +10 -0
  376. package/dist/physics/body/collider-shape/mass-properties.js +48 -0
  377. package/dist/physics/body/collider-shape/mass-properties.js.map +1 -0
  378. package/dist/physics/body/collider-shape/public.d.ts +4 -0
  379. package/dist/physics/body/collider-shape/public.js +6 -0
  380. package/dist/physics/body/collider-shape/public.js.map +1 -0
  381. package/dist/physics/body/collider-shape/schema.d.ts +4 -0
  382. package/dist/physics/body/collider-shape/schema.js +3 -0
  383. package/dist/physics/body/collider-shape/schema.js.map +1 -0
  384. package/dist/physics/body/collider-shape/to-index.d.ts +3 -0
  385. package/dist/physics/body/collider-shape/to-index.js +6 -0
  386. package/dist/physics/body/collider-shape/to-index.js.map +1 -0
  387. package/dist/physics/body/rigid-body.d.ts +23 -0
  388. package/dist/physics/body/rigid-body.js +3 -0
  389. package/dist/physics/body/rigid-body.js.map +1 -0
  390. package/dist/physics/body/static-collider.d.ts +25 -0
  391. package/dist/physics/body/static-collider.js +3 -0
  392. package/dist/physics/body/static-collider.js.map +1 -0
  393. package/dist/physics/joint/joint-plugin.d.ts +88 -0
  394. package/dist/physics/joint/joint-plugin.js +32 -0
  395. package/dist/physics/joint/joint-plugin.js.map +1 -0
  396. package/dist/physics/joint/joint-type/joint-type.d.ts +15 -0
  397. package/dist/physics/joint/joint-type/joint-type.js +3 -0
  398. package/dist/physics/joint/joint-type/joint-type.js.map +1 -0
  399. package/dist/physics/joint/joint-type/public.d.ts +1 -0
  400. package/dist/physics/joint/joint-type/public.js +3 -0
  401. package/dist/physics/joint/joint-type/public.js.map +1 -0
  402. package/dist/physics/joint/joint-type/schema.d.ts +4 -0
  403. package/dist/physics/joint/joint-type/schema.js +3 -0
  404. package/dist/physics/joint/joint-type/schema.js.map +1 -0
  405. package/dist/physics/joint/joint.d.ts +24 -0
  406. package/dist/physics/joint/joint.js +3 -0
  407. package/dist/physics/joint/joint.js.map +1 -0
  408. package/dist/physics/physics-clock-plugin.d.ts +86 -0
  409. package/dist/physics/physics-clock-plugin.js +37 -0
  410. package/dist/physics/physics-clock-plugin.js.map +1 -0
  411. package/dist/physics/physics-clock.test.d.ts +1 -0
  412. package/dist/physics/physics-clock.test.js +45 -0
  413. package/dist/physics/physics-clock.test.js.map +1 -0
  414. package/dist/physics/physics-data-plugin.d.ts +348 -0
  415. package/dist/physics/physics-data-plugin.js +71 -0
  416. package/dist/physics/physics-data-plugin.js.map +1 -0
  417. package/dist/physics/ragdoll/fit-bone-capsules.d.ts +39 -0
  418. package/dist/physics/ragdoll/fit-bone-capsules.js +87 -0
  419. package/dist/physics/ragdoll/fit-bone-capsules.js.map +1 -0
  420. package/dist/physics/ragdoll/fit-bone-capsules.test.d.ts +1 -0
  421. package/dist/physics/ragdoll/fit-bone-capsules.test.js +67 -0
  422. package/dist/physics/ragdoll/fit-bone-capsules.test.js.map +1 -0
  423. package/dist/physics/solvers/jolt-solver-plugin.d.ts +465 -0
  424. package/dist/physics/solvers/jolt-solver-plugin.js +440 -0
  425. package/dist/physics/solvers/jolt-solver-plugin.js.map +1 -0
  426. package/dist/physics/solvers/rapier-jolt.benchmark.test.d.ts +1 -0
  427. package/dist/physics/solvers/rapier-jolt.benchmark.test.js +35 -0
  428. package/dist/physics/solvers/rapier-jolt.benchmark.test.js.map +1 -0
  429. package/dist/physics/solvers/rapier-solver-plugin.d.ts +444 -0
  430. package/dist/physics/solvers/rapier-solver-plugin.js +284 -0
  431. package/dist/physics/solvers/rapier-solver-plugin.js.map +1 -0
  432. package/dist/physics/solvers/solver-benchmark.d.ts +45 -0
  433. package/dist/physics/solvers/solver-benchmark.js +115 -0
  434. package/dist/physics/solvers/solver-benchmark.js.map +1 -0
  435. package/package.json +34 -0
  436. package/src/core/core-plugin.ts +92 -0
  437. package/src/core/frame-time/frame-time-plugin.ts +44 -0
  438. package/src/core/frame-time/frame-time.ts +21 -0
  439. package/src/core/frame-time/public.ts +3 -0
  440. package/src/graphics/animation/animation-data-plugin.ts +119 -0
  441. package/src/graphics/animation/animation-plugin.test.ts +161 -0
  442. package/src/graphics/animation/animation-plugin.ts +26 -0
  443. package/src/graphics/animation/animation-track/animation-track.ts +17 -0
  444. package/src/graphics/animation/animation-track/componentwise-lerp.ts +24 -0
  445. package/src/graphics/animation/animation-track/interpolate.ts +24 -0
  446. package/src/graphics/animation/animation-track/public.ts +3 -0
  447. package/src/graphics/animation/animation-track/sample.ts +48 -0
  448. package/src/graphics/animation/interpolation-mode/interpolation-mode.ts +8 -0
  449. package/src/graphics/animation/interpolation-mode/public.ts +3 -0
  450. package/src/graphics/animation/interpolation-mode/schema.ts +5 -0
  451. package/src/graphics/camera/camera-plugin.ts +37 -0
  452. package/src/graphics/camera/camera.ts +8 -0
  453. package/src/graphics/camera/orbit/attach-orbit-drag.ts +62 -0
  454. package/src/graphics/camera/orbit/orbit-data-plugin.ts +44 -0
  455. package/src/graphics/camera/orbit/orbit-plugin.ts +13 -0
  456. package/src/graphics/camera/orbit/orbit-system-plugin.ts +74 -0
  457. package/src/graphics/camera/orbit/orbit.ts +36 -0
  458. package/src/graphics/camera/orbit/public.ts +7 -0
  459. package/src/graphics/camera/public.ts +6 -0
  460. package/src/graphics/camera/schema.ts +21 -0
  461. package/src/graphics/camera/screen-to-world-ray.ts +47 -0
  462. package/src/graphics/camera/to-view-projection.ts +29 -0
  463. package/src/graphics/graphics-plugin.ts +108 -0
  464. package/src/graphics/picking/pick-hit.ts +13 -0
  465. package/src/graphics/picking/picking-plugin.ts +101 -0
  466. package/src/graphics/plugins.md +120 -0
  467. package/src/graphics/rendering/bone-collider-plugin.ts +182 -0
  468. package/src/graphics/rendering/display-transform-plugin.ts +26 -0
  469. package/src/graphics/rendering/ibl-render/brdf.wgsl.ts +43 -0
  470. package/src/graphics/rendering/ibl-render/ibl/brdf-lut.ts +101 -0
  471. package/src/graphics/rendering/ibl-render/ibl/build-ibl-resources.ts +57 -0
  472. package/src/graphics/rendering/ibl-render/ibl/create-cubemap.ts +17 -0
  473. package/src/graphics/rendering/ibl-render/ibl/cube-face-view.ts +11 -0
  474. package/src/graphics/rendering/ibl-render/ibl/cubemap-sample-view.ts +9 -0
  475. package/src/graphics/rendering/ibl-render/ibl/environment.ts +190 -0
  476. package/src/graphics/rendering/ibl-render/ibl/float-to-half.ts +35 -0
  477. package/src/graphics/rendering/ibl-render/ibl/ibl-math.wgsl.ts +60 -0
  478. package/src/graphics/rendering/ibl-render/ibl/irradiance.ts +105 -0
  479. package/src/graphics/rendering/ibl-render/ibl/parse-hdr.ts +108 -0
  480. package/src/graphics/rendering/ibl-render/ibl/prefilter.ts +121 -0
  481. package/src/graphics/rendering/ibl-render/ibl/render-helpers.ts +17 -0
  482. package/src/graphics/rendering/ibl-render/ibl-render-plugin.ts +415 -0
  483. package/src/graphics/rendering/ibl-render/ibl-shader.wgsl.ts +185 -0
  484. package/src/graphics/rendering/ibl-render/skybox-shader.wgsl.ts +51 -0
  485. package/src/graphics/rendering/interpolation-plugin.ts +97 -0
  486. package/src/graphics/rendering/interpolation.test.ts +52 -0
  487. package/src/graphics/rendering/jolt-ragdoll-plugin.ts +174 -0
  488. package/src/graphics/rendering/material-gpu/material-arrays.ts +113 -0
  489. package/src/graphics/rendering/material-gpu/material-bind-group.ts +61 -0
  490. package/src/graphics/rendering/material-gpu/material-gpu-plugin.ts +95 -0
  491. package/src/graphics/rendering/model-collider-plugin.ts +77 -0
  492. package/src/graphics/rendering/pbr-core-plugin.ts +40 -0
  493. package/src/graphics/rendering/pbr-render/pbr-array-shader.wgsl.ts +146 -0
  494. package/src/graphics/rendering/pbr-render/pbr-render-plugin.ts +247 -0
  495. package/src/graphics/rendering/pbr-render/physics-bridge-plugin.ts +106 -0
  496. package/src/graphics/rendering/ragdoll-trigger-plugin.ts +21 -0
  497. package/src/graphics/rendering/rendering-plugin.ts +3 -0
  498. package/src/graphics/rendering/skinning/skinning-attributes/layout.ts +20 -0
  499. package/src/graphics/rendering/skinning/skinning-attributes/public.ts +3 -0
  500. package/src/graphics/rendering/skinning/skinning-attributes/skinning-attributes.ts +3 -0
  501. package/src/graphics/rendering/skinning/skinning-plugin.ts +213 -0
  502. package/src/graphics/rendering/standard-vertex/layout.ts +19 -0
  503. package/src/graphics/rendering/standard-vertex/public.ts +4 -0
  504. package/src/graphics/rendering/standard-vertex/schema.ts +17 -0
  505. package/src/graphics/rendering/standard-vertex/standard-vertex.ts +8 -0
  506. package/src/graphics/rendering/visible-material/color-material-options.ts +10 -0
  507. package/src/graphics/rendering/visible-material/create-bind-group-layout.ts +35 -0
  508. package/src/graphics/rendering/visible-material/create-color-bind-group.ts +40 -0
  509. package/src/graphics/rendering/visible-material/public.ts +6 -0
  510. package/src/graphics/rendering/visible-material/schema.ts +25 -0
  511. package/src/graphics/rendering/visible-material/visible-material.ts +8 -0
  512. package/src/graphics/scene/light/light-plugin.ts +37 -0
  513. package/src/graphics/scene/light/light.ts +18 -0
  514. package/src/graphics/scene/light/public.ts +1 -0
  515. package/src/graphics/scene/model/geometry/geometry.ts +12 -0
  516. package/src/graphics/scene/model/geometry/public.ts +4 -0
  517. package/src/graphics/scene/model/gltf/accessor-view.ts +53 -0
  518. package/src/graphics/scene/model/gltf/build-material-bind-group.ts +110 -0
  519. package/src/graphics/scene/model/gltf/compute-world-matrices.ts +43 -0
  520. package/src/graphics/scene/model/gltf/create-color-material.ts +47 -0
  521. package/src/graphics/scene/model/gltf/decode-images.ts +93 -0
  522. package/src/graphics/scene/model/gltf/gltf-schema.ts +161 -0
  523. package/src/graphics/scene/model/gltf/load-gltf-model.ts +220 -0
  524. package/src/graphics/scene/model/gltf/pack-vertex-buffer.ts +116 -0
  525. package/src/graphics/scene/model/gltf/parse-animations.ts +66 -0
  526. package/src/graphics/scene/model/gltf/parse-glb.ts +51 -0
  527. package/src/graphics/scene/model/gltf/parse-skin.ts +67 -0
  528. package/src/graphics/scene/model/model-loader-plugin.ts +131 -0
  529. package/src/graphics/scene/model/model-plugin.ts +46 -0
  530. package/src/graphics/scene/model/model.ts +15 -0
  531. package/src/graphics/scene/model/public.ts +1 -0
  532. package/src/graphics/scene/model/shape/convex-hull.test.ts +72 -0
  533. package/src/graphics/scene/model/shape/convex-hull.ts +141 -0
  534. package/src/graphics/scene/model/shape/shape-geometry-plugin.ts +61 -0
  535. package/src/graphics/scene/model/shape/shape-mesh.ts +150 -0
  536. package/src/graphics/scene/model/shape/upload-shape-mesh.ts +14 -0
  537. package/src/graphics/scene/model/world-bounds-plugin.ts +88 -0
  538. package/src/graphics/scene/node/node-data-plugin.ts +28 -0
  539. package/src/graphics/scene/node/node-plugin.ts +13 -0
  540. package/src/graphics/scene/node/node.ts +23 -0
  541. package/src/graphics/scene/node/public.ts +1 -0
  542. package/src/graphics/scene/node/transform-plugin.ts +72 -0
  543. package/src/graphics/scene/scene-plugin.ts +20 -0
  544. package/src/graphics/scene/scene-uniforms/create-bind-group-layout.ts +19 -0
  545. package/src/graphics/scene/scene-uniforms/public.ts +5 -0
  546. package/src/graphics/scene/scene-uniforms/scene-uniforms-plugin.ts +64 -0
  547. package/src/graphics/scene/scene-uniforms/scene-uniforms.ts +15 -0
  548. package/src/graphics/scene/scene-uniforms/schema.ts +17 -0
  549. package/src/index.ts +72 -0
  550. package/src/material/material-plugin.ts +61 -0
  551. package/src/material/material.ts +38 -0
  552. package/src/material/public.ts +4 -0
  553. package/src/material/standard-materials.ts +43 -0
  554. package/src/physics/README.md +71 -0
  555. package/src/physics/body/body-type/body-type.ts +14 -0
  556. package/src/physics/body/body-type/is-dynamic.ts +8 -0
  557. package/src/physics/body/body-type/public.ts +4 -0
  558. package/src/physics/body/body-type/schema.ts +5 -0
  559. package/src/physics/body/collider-mesh.ts +13 -0
  560. package/src/physics/body/collider-shape/collider-shape.ts +19 -0
  561. package/src/physics/body/collider-shape/list.ts +7 -0
  562. package/src/physics/body/collider-shape/mass-properties.ts +47 -0
  563. package/src/physics/body/collider-shape/public.ts +6 -0
  564. package/src/physics/body/collider-shape/schema.ts +5 -0
  565. package/src/physics/body/collider-shape/to-index.ts +8 -0
  566. package/src/physics/body/rigid-body.ts +26 -0
  567. package/src/physics/body/static-collider.ts +28 -0
  568. package/src/physics/joint/joint-plugin.ts +33 -0
  569. package/src/physics/joint/joint-type/joint-type.ts +19 -0
  570. package/src/physics/joint/joint-type/public.ts +3 -0
  571. package/src/physics/joint/joint-type/schema.ts +5 -0
  572. package/src/physics/joint/joint.ts +27 -0
  573. package/src/physics/physics-clock-plugin.ts +61 -0
  574. package/src/physics/physics-clock.test.ts +55 -0
  575. package/src/physics/physics-data-plugin.ts +73 -0
  576. package/src/physics/ragdoll/fit-bone-capsules.test.ts +66 -0
  577. package/src/physics/ragdoll/fit-bone-capsules.ts +106 -0
  578. package/src/physics/solvers/README.md +63 -0
  579. package/src/physics/solvers/jolt-solver-plugin.ts +382 -0
  580. package/src/physics/solvers/rapier-jolt.benchmark.test.ts +39 -0
  581. package/src/physics/solvers/rapier-solver-plugin.ts +251 -0
  582. package/src/physics/solvers/solver-benchmark.ts +172 -0
  583. package/tsconfig.json +25 -0
  584. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,382 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import initJolt from "jolt-physics";
4
+ import { Database, type Entity } from "@adobe/data/ecs";
5
+ import { True } from "@adobe/data/schema";
6
+ import { physicsClock } from "../physics-clock-plugin.js";
7
+ import { physicsData } from "../physics-data-plugin.js";
8
+ import { jointData } from "../joint/joint-plugin.js";
9
+ import { BodyType } from "../body/body-type/body-type.js";
10
+ import { ColliderShape } from "../body/collider-shape/collider-shape.js";
11
+ import type { ColliderMesh } from "../body/collider-mesh.js";
12
+
13
+ /**
14
+ * A third rigid-body solver behind the same `physicsData` seam — Jolt Physics
15
+ * (Jorrit Rouwe, C++→WASM, the engine from *Horizon Forbidden West*). Like the
16
+ * Rapier plugin it reads the identical authored components (`RigidBody` +
17
+ * `StaticCollider`) and writes back `position`/`rotation`/velocity for dynamic
18
+ * bodies, so the same scene runs unchanged on rapierSolver / joltSolver.
19
+ *
20
+ * Jolt's WASM initialises asynchronously; per the repo's no-top-level-await rule
21
+ * the init promise lives in the system closure and the system no-ops until the
22
+ * world exists, then runs every frame. All interop with the Emscripten binding
23
+ * is contained in this one module.
24
+ */
25
+
26
+ const GRAVITY = 18; // matches rapierSolver so the two solvers are directly comparable
27
+
28
+ // Object layers (Jolt's collision-filtering requirement): statics don't collide
29
+ // with each other; dynamics collide with everything; the RAGDOLL layer collides
30
+ // with the world (static + dynamic) but NOT itself — so a collisionGroup>0 body
31
+ // (a ragdoll's bones) never self-collides.
32
+ const L_STATIC = 0, L_DYNAMIC = 1, L_RAGDOLL = 2, NUM_OBJECT_LAYERS = 3;
33
+ const BP_STATIC = 0, BP_DYNAMIC = 1, NUM_BP_LAYERS = 2;
34
+
35
+ const RIGID = ["bodyType", "colliderShape", "halfExtents", "material", "position", "rotation", "linearVelocity", "angularVelocity"] as const;
36
+ const STATIC = ["colliderShape", "halfExtents", "material", "position", "rotation"] as const;
37
+ // Dynamic bodies carry the derived prev-pose snapshot (added on first sync) used
38
+ // for render interpolation; this query reads/writes it alongside the live pose.
39
+ const SNAPSHOT = ["bodyType", "position", "rotation", "_prevPosition", "_prevRotation"] as const;
40
+ // Sync only over bodies not yet mirrored into Jolt (excluded by the `_joltBody`
41
+ // tag added on creation) → steady state iterates zero rows instead of
42
+ // re-scanning every body each frame.
43
+ const NEW_RIGID = { exclude: ["_joltBody"] } as const;
44
+ const NEW_STATIC = { exclude: ["linearVelocity", "_joltBody"] } as const;
45
+ // Kinematic bodies, by archetype shape (no per-row value test): they have
46
+ // `bodyType` (so not a StaticCollider) and are mirrored (`_joltBody`) but never
47
+ // gained `_prevPosition` (only dynamics do) — so excluding it isolates kinematics.
48
+ const KINEMATIC = ["bodyType", "position", "rotation", "_joltBody"] as const;
49
+ const KINEMATIC_ONLY = { exclude: ["_prevPosition"] } as const;
50
+ const JOINT = ["jointType", "jointBodyA", "jointBodyB", "jointAnchorA", "jointAnchorB", "jointAxis", "jointMinLimit", "jointMaxLimit", "jointSwingLimit"] as const;
51
+ const NEW_JOINT = { exclude: ["_joltJoint"] } as const;
52
+
53
+ type JoltModule = Awaited<ReturnType<typeof initJolt>>;
54
+ type JBody = InstanceType<JoltModule["Body"]>;
55
+ type JBodyInterface = InstanceType<JoltModule["BodyInterface"]>;
56
+ type JJoltInterface = InstanceType<JoltModule["JoltInterface"]>;
57
+ type JRVec3 = InstanceType<JoltModule["RVec3"]>;
58
+ type JQuat = InstanceType<JoltModule["Quat"]>;
59
+ type JVec3 = InstanceType<JoltModule["Vec3"]>;
60
+ type JShape = InstanceType<JoltModule["Shape"]>;
61
+ type JPhysicsSystem = InstanceType<JoltModule["PhysicsSystem"]>;
62
+
63
+ interface MatProps { restitution: number; friction: number }
64
+
65
+ /** The live Jolt world, published once WASM init completes, so Jolt-native
66
+ * extensions (e.g. `joltRagdoll`) can add their own bodies/constraints into the
67
+ * same physics system the solver steps. The RAGDOLL object layer (no
68
+ * self-collision) is exposed for ragdoll parts. */
69
+ export interface JoltContext {
70
+ jolt: JoltModule;
71
+ physicsSystem: JPhysicsSystem;
72
+ bodyInterface: JBodyInterface;
73
+ ragdollLayer: number;
74
+ }
75
+
76
+ export const joltSolver = Database.Plugin.create({
77
+ extends: Database.Plugin.combine(physicsData, jointData, physicsClock),
78
+ components: {
79
+ _joltBody: True.schema, // tag: this body has been mirrored into the Jolt world
80
+ _joltJoint: True.schema, // tag: this joint has been mirrored into the Jolt world
81
+ },
82
+ resources: {
83
+ _joltContext: { default: null as JoltContext | null, transient: true },
84
+ },
85
+ systems: {
86
+ joltStep: {
87
+ schedule: { during: ["physics"], after: ["advancePhysicsClock"] },
88
+ create: db => {
89
+ let J: JoltModule | null = null;
90
+ let initStarted = false;
91
+ let joltInterface: JJoltInterface | null = null;
92
+ let bodyInterface: JBodyInterface | null = null;
93
+ let physicsSystem: JPhysicsSystem | null = null;
94
+ let kPos: JRVec3 | null = null, kRot: JQuat | null = null; // reused kinematic-drive temporaries
95
+ const bodies = new Map<Entity, JBody>(); // entity → Jolt body
96
+
97
+ const matPropsOf = (id: Entity): MatProps => {
98
+ const m = db.store.read(id) as { restitution?: number; friction?: number } | null;
99
+ return { restitution: m?.restitution ?? 0.2, friction: m?.friction ?? 0.5 };
100
+ };
101
+
102
+ // hull/mesh colliders may be auto-generated from a model that's still
103
+ // loading — defer mirroring such a body until its collision data exists.
104
+ const colliderReady = (id: Entity, shape: ColliderShape): boolean => {
105
+ if (shape !== "hull" && shape !== "mesh") return true;
106
+ const r = db.store.read(id) as { convexPoints?: unknown; colliderMesh?: unknown } | null;
107
+ return !!(r?.convexPoints || r?.colliderMesh);
108
+ };
109
+
110
+ // Jolt joints anchor in world space; map each body-local anchor (and the
111
+ // hinge axis) to world using the body's spawn pose. Reused scratch triples.
112
+ const rotateInto = (q: ArrayLike<number>, vx: number, vy: number, vz: number, out: [number, number, number]): void => {
113
+ const qx = q[0], qy = q[1], qz = q[2], qw = q[3];
114
+ const tx = 2 * (qy * vz - qz * vy), ty = 2 * (qz * vx - qx * vz), tz = 2 * (qx * vy - qy * vx);
115
+ out[0] = vx + qw * tx + (qy * tz - qz * ty);
116
+ out[1] = vy + qw * ty + (qz * tx - qx * tz);
117
+ out[2] = vz + qw * tz + (qx * ty - qy * tx);
118
+ };
119
+ const perpInto = (v: ArrayLike<number>, out: [number, number, number]): void => {
120
+ if (Math.abs(v[0]) <= Math.abs(v[1]) && Math.abs(v[0]) <= Math.abs(v[2])) { out[0] = 0; out[1] = v[2]; out[2] = -v[1]; }
121
+ else { out[0] = -v[2]; out[1] = 0; out[2] = v[0]; }
122
+ const l = Math.hypot(out[0], out[1], out[2]) || 1; out[0] /= l; out[1] /= l; out[2] /= l;
123
+ };
124
+ const wa: [number, number, number] = [0, 0, 0], wb: [number, number, number] = [0, 0, 0];
125
+ const wAxis: [number, number, number] = [0, 0, 0], wNorm: [number, number, number] = [0, 0, 0];
126
+
127
+ const setup = (jolt: JoltModule): void => {
128
+ const objectFilter = new jolt.ObjectLayerPairFilterTable(NUM_OBJECT_LAYERS);
129
+ objectFilter.EnableCollision(L_STATIC, L_DYNAMIC);
130
+ objectFilter.EnableCollision(L_DYNAMIC, L_DYNAMIC);
131
+ objectFilter.EnableCollision(L_STATIC, L_RAGDOLL);
132
+ objectFilter.EnableCollision(L_DYNAMIC, L_RAGDOLL); // ragdoll collides with the world, not itself
133
+ const bp = new jolt.BroadPhaseLayerInterfaceTable(NUM_OBJECT_LAYERS, NUM_BP_LAYERS);
134
+ bp.MapObjectToBroadPhaseLayer(L_STATIC, new jolt.BroadPhaseLayer(BP_STATIC));
135
+ bp.MapObjectToBroadPhaseLayer(L_DYNAMIC, new jolt.BroadPhaseLayer(BP_DYNAMIC));
136
+ bp.MapObjectToBroadPhaseLayer(L_RAGDOLL, new jolt.BroadPhaseLayer(BP_DYNAMIC));
137
+ const settings = new jolt.JoltSettings();
138
+ settings.mObjectLayerPairFilter = objectFilter;
139
+ settings.mBroadPhaseLayerInterface = bp;
140
+ settings.mObjectVsBroadPhaseLayerFilter = new jolt.ObjectVsBroadPhaseLayerFilterTable(bp, NUM_BP_LAYERS, objectFilter, NUM_OBJECT_LAYERS);
141
+ joltInterface = new jolt.JoltInterface(settings);
142
+ jolt.destroy(settings);
143
+ physicsSystem = joltInterface.GetPhysicsSystem();
144
+ const g = new jolt.Vec3(0, -GRAVITY, 0);
145
+ physicsSystem.SetGravity(g);
146
+ jolt.destroy(g);
147
+ bodyInterface = physicsSystem.GetBodyInterface();
148
+ kPos = new jolt.RVec3(0, 0, 0); kRot = new jolt.Quat(0, 0, 0, 1);
149
+ };
150
+
151
+ const ensureBody = (jolt: JoltModule, bi: JBodyInterface, id: Entity, motion: BodyType, shape: ColliderShape, hx: number, hy: number, hz: number, mat: Entity, px: number, py: number, pz: number, q: ArrayLike<number>, vx: number, vy: number, vz: number, wx: number, wy: number, wz: number): void => {
152
+ if (bodies.has(id)) return;
153
+ const m = matPropsOf(mat);
154
+ // box needs a Vec3 half-extent temporary; sphere/capsule are scalar;
155
+ // hull is built from the authored point cloud (read once here).
156
+ // capsule: Y-aligned, halfHeight = cylinder half (hy), radius = hx.
157
+ let half: JVec3 | null = null;
158
+ let shp: JShape;
159
+ if (shape === "sphere") shp = new jolt.SphereShape(hx);
160
+ else if (shape === "capsule") shp = new jolt.CapsuleShape(hy, hx);
161
+ else if (shape === "hull") {
162
+ const pts = (db.store.read(id) as { convexPoints?: Float32Array | null }).convexPoints;
163
+ const hs = new jolt.ConvexHullShapeSettings();
164
+ if (pts) for (let i = 0; i < pts.length; i += 3) {
165
+ const v = new jolt.Vec3(pts[i], pts[i + 1], pts[i + 2]);
166
+ hs.mPoints.push_back(v); jolt.destroy(v); // push_back copies the value
167
+ }
168
+ const res = hs.Create();
169
+ shp = res.IsValid() ? res.Get() : new jolt.SphereShape(Math.max(hx, 0.1)); // degenerate fallback
170
+ jolt.destroy(hs);
171
+ } else if (shape === "mesh") {
172
+ const cm = (db.store.read(id) as { colliderMesh?: ColliderMesh | null }).colliderMesh;
173
+ const verts = new jolt.VertexList(), tris = new jolt.IndexedTriangleList(), mats = new jolt.PhysicsMaterialList();
174
+ if (cm) {
175
+ for (let i = 0; i < cm.positions.length; i += 3) {
176
+ const f = new jolt.Float3(cm.positions[i], cm.positions[i + 1], cm.positions[i + 2]);
177
+ verts.push_back(f); jolt.destroy(f); // copied by value
178
+ }
179
+ for (let i = 0; i < cm.indices.length; i += 3) {
180
+ const t = new jolt.IndexedTriangle(cm.indices[i], cm.indices[i + 1], cm.indices[i + 2], 0);
181
+ tris.push_back(t); jolt.destroy(t);
182
+ }
183
+ }
184
+ const ms = new jolt.MeshShapeSettings(verts, tris, mats);
185
+ const res = ms.Create();
186
+ shp = res.IsValid() ? res.Get() : new jolt.SphereShape(0.1);
187
+ jolt.destroy(ms); jolt.destroy(verts); jolt.destroy(tris); jolt.destroy(mats);
188
+ } else { half = new jolt.Vec3(hx, hy, hz); shp = new jolt.BoxShape(half); }
189
+ const pos = new jolt.RVec3(px, py, pz), rot = new jolt.Quat(q[0], q[1], q[2], q[3]);
190
+ // dynamic = simulated; kinematic = position-driven (pushes dynamics, in the
191
+ // dynamic layer so it collides with them); static = immovable collider.
192
+ const motionType = motion === "dynamic" ? jolt.EMotionType_Dynamic
193
+ : motion === "kinematic" ? jolt.EMotionType_Kinematic : jolt.EMotionType_Static;
194
+ // collisionGroup>0 ⇒ the no-self-collide RAGDOLL layer.
195
+ const grp = (db.store.read(id) as { collisionGroup?: number } | null)?.collisionGroup ?? 0;
196
+ const layer = motion === "static" ? L_STATIC : grp > 0 ? L_RAGDOLL : L_DYNAMIC;
197
+ const settings = new jolt.BodyCreationSettings(shp, pos, rot, motionType, layer);
198
+ settings.mRestitution = m.restitution;
199
+ settings.mFriction = m.friction;
200
+ const body = bi.CreateBody(settings);
201
+ bi.AddBody(body.GetID(), motion === "static" ? jolt.EActivation_DontActivate : jolt.EActivation_Activate);
202
+ if (motion === "dynamic" && (vx || vy || vz || wx || wy || wz)) {
203
+ const lv = new jolt.Vec3(vx, vy, vz), av = new jolt.Vec3(wx, wy, wz);
204
+ bi.SetLinearAndAngularVelocity(body.GetID(), lv, av);
205
+ jolt.destroy(lv); jolt.destroy(av);
206
+ }
207
+ bodies.set(id, body);
208
+ // free the construction temporaries (the body keeps a ref to the shape)
209
+ jolt.destroy(settings); jolt.destroy(pos); jolt.destroy(rot);
210
+ if (half) jolt.destroy(half);
211
+ };
212
+
213
+ return () => {
214
+ if (!J || !bodyInterface || !joltInterface) {
215
+ if (!initStarted) {
216
+ initStarted = true;
217
+ initJolt().then((j: JoltModule) => {
218
+ J = j; setup(j);
219
+ db.store.resources._joltContext = { jolt: j, physicsSystem: physicsSystem!, bodyInterface: bodyInterface!, ragdollLayer: L_RAGDOLL };
220
+ });
221
+ }
222
+ return; // WASM not ready yet
223
+ }
224
+ const jolt = J, bi = bodyInterface;
225
+
226
+ // sync: mirror only bodies not yet in Jolt (excluded by tag),
227
+ // then tag them. Tail→head since every row migrates out on
228
+ // tagging; reads via column accessors (robust to migration, and
229
+ // this loop only touches genuinely-new bodies, so it's cold).
230
+ for (const arch of db.store.queryArchetypes(RIGID, NEW_RIGID)) {
231
+ const ids = arch.columns.id, bt = arch.columns.bodyType, cs = arch.columns.colliderShape, mat = arch.columns.material;
232
+ const he = arch.columns.halfExtents, pos = arch.columns.position, ori = arch.columns.rotation, lv = arch.columns.linearVelocity, av = arch.columns.angularVelocity;
233
+ for (let r = arch.rowCount - 1; r >= 0; r--) {
234
+ const id = ids.get(r), bodyType = bt.get(r), shape = cs.get(r), h = he.get(r), p = pos.get(r), o = ori.get(r), v = lv.get(r), w = av.get(r);
235
+ if (!colliderReady(id, shape)) continue; // auto-collider not generated yet
236
+ ensureBody(jolt, bi, id, bodyType, shape, h[0], h[1], h[2], mat.get(r), p[0], p[1], p[2], o, v[0], v[1], v[2], w[0], w[1], w[2]);
237
+ // Tag as mirrored. Dynamics also migrate onto the derived prev-pose
238
+ // snapshot (the interpolator reads it); kinematic bodies are authored
239
+ // each frame, so they render at the live pose with no snapshot — the
240
+ // _prevPosition absence is exactly what the kinematic-drive query keys on.
241
+ db.store.update(id, BodyType.isDynamic(bodyType) ? { _joltBody: true, _prevPosition: p, _prevRotation: o } : { _joltBody: true });
242
+ }
243
+ }
244
+ for (const arch of db.store.queryArchetypes(STATIC, NEW_STATIC)) {
245
+ const ids = arch.columns.id, cs = arch.columns.colliderShape, mat = arch.columns.material;
246
+ const he = arch.columns.halfExtents, pos = arch.columns.position, ori = arch.columns.rotation;
247
+ for (let r = arch.rowCount - 1; r >= 0; r--) {
248
+ const id = ids.get(r), shape = cs.get(r), h = he.get(r), p = pos.get(r);
249
+ if (!colliderReady(id, shape)) continue; // auto-collider not generated yet
250
+ ensureBody(jolt, bi, id, "static", shape, h[0], h[1], h[2], mat.get(r), p[0], p[1], p[2], ori.get(r), 0, 0, 0, 0, 0, 0);
251
+ db.store.update(id, { _joltBody: true });
252
+ }
253
+ }
254
+
255
+ // Mirror new joints once both bodies exist (tag + exclude; tail→head).
256
+ // Anchors/axes are body-local; map to world (Jolt WorldSpace) via spawn pose.
257
+ for (const arch of db.store.queryArchetypes(JOINT, NEW_JOINT)) {
258
+ const ids = arch.columns.id, jt = arch.columns.jointType, ba = arch.columns.jointBodyA, bbc = arch.columns.jointBodyB;
259
+ const aa = arch.columns.jointAnchorA, ab = arch.columns.jointAnchorB, axc = arch.columns.jointAxis, lo = arch.columns.jointMinLimit, hi = arch.columns.jointMaxLimit, sw = arch.columns.jointSwingLimit;
260
+ for (let r = arch.rowCount - 1; r >= 0; r--) {
261
+ const a = bodies.get(ba.get(r)), b = bodies.get(bbc.get(r));
262
+ if (!a || !b || !physicsSystem) continue; // a body isn't mirrored yet — retry next frame
263
+ const recA = db.store.read(ba.get(r)) as { position: ArrayLike<number>; rotation: ArrayLike<number> };
264
+ const recB = db.store.read(bbc.get(r)) as { position: ArrayLike<number>; rotation: ArrayLike<number> };
265
+ const an = aa.get(r), bn = ab.get(r);
266
+ rotateInto(recA.rotation, an[0], an[1], an[2], wa); wa[0] += recA.position[0]; wa[1] += recA.position[1]; wa[2] += recA.position[2];
267
+ rotateInto(recB.rotation, bn[0], bn[1], bn[2], wb); wb[0] += recB.position[0]; wb[1] += recB.position[1]; wb[2] += recB.position[2];
268
+ const p1 = new jolt.RVec3(wa[0], wa[1], wa[2]), p2 = new jolt.RVec3(wb[0], wb[1], wb[2]);
269
+ const temps: { __brand?: never }[] = [p1, p2];
270
+ const type = jt.get(r);
271
+ let settings: InstanceType<JoltModule["TwoBodyConstraintSettings"]>;
272
+ if (type === "hinge") {
273
+ const ax = axc.get(r);
274
+ rotateInto(recA.rotation, ax[0], ax[1], ax[2], wAxis); perpInto(wAxis, wNorm);
275
+ const h1 = new jolt.Vec3(wAxis[0], wAxis[1], wAxis[2]), h2 = new jolt.Vec3(wAxis[0], wAxis[1], wAxis[2]);
276
+ const n1 = new jolt.Vec3(wNorm[0], wNorm[1], wNorm[2]), n2 = new jolt.Vec3(wNorm[0], wNorm[1], wNorm[2]);
277
+ const hs = new jolt.HingeConstraintSettings();
278
+ hs.mSpace = jolt.EConstraintSpace_WorldSpace; hs.mPoint1 = p1; hs.mPoint2 = p2;
279
+ hs.mHingeAxis1 = h1; hs.mHingeAxis2 = h2; hs.mNormalAxis1 = n1; hs.mNormalAxis2 = n2;
280
+ const min = lo.get(r), max = hi.get(r); if (min < max) { hs.mLimitsMin = min; hs.mLimitsMax = max; }
281
+ settings = hs; temps.push(h1, h2, n1, n2, hs);
282
+ } else if (type === "cone") {
283
+ // swing-twist: bone axis bound to a (symmetric) cone around the
284
+ // reference axis, plus a twist range about it — anatomical limits.
285
+ const ax = axc.get(r);
286
+ rotateInto(recA.rotation, ax[0], ax[1], ax[2], wAxis); perpInto(wAxis, wNorm);
287
+ const t1 = new jolt.Vec3(wAxis[0], wAxis[1], wAxis[2]), t2 = new jolt.Vec3(wAxis[0], wAxis[1], wAxis[2]);
288
+ const pa1 = new jolt.Vec3(wNorm[0], wNorm[1], wNorm[2]), pa2 = new jolt.Vec3(wNorm[0], wNorm[1], wNorm[2]);
289
+ const cs = new jolt.SwingTwistConstraintSettings();
290
+ cs.mSpace = jolt.EConstraintSpace_WorldSpace; cs.mPosition1 = p1; cs.mPosition2 = p2;
291
+ cs.mTwistAxis1 = t1; cs.mTwistAxis2 = t2; cs.mPlaneAxis1 = pa1; cs.mPlaneAxis2 = pa2;
292
+ cs.mSwingType = jolt.ESwingType_Cone;
293
+ const swing = sw.get(r); cs.mNormalHalfConeAngle = swing; cs.mPlaneHalfConeAngle = swing;
294
+ const min = lo.get(r), max = hi.get(r);
295
+ cs.mTwistMinAngle = min < max ? min : -Math.PI; cs.mTwistMaxAngle = min < max ? max : Math.PI;
296
+ settings = cs; temps.push(t1, t2, pa1, pa2, cs);
297
+ } else if (type === "fixed") {
298
+ const fs = new jolt.FixedConstraintSettings(); fs.mSpace = jolt.EConstraintSpace_WorldSpace; fs.mPoint1 = p1; fs.mPoint2 = p2;
299
+ settings = fs; temps.push(fs);
300
+ } else {
301
+ const ps = new jolt.PointConstraintSettings(); ps.mSpace = jolt.EConstraintSpace_WorldSpace; ps.mPoint1 = p1; ps.mPoint2 = p2;
302
+ settings = ps; temps.push(ps);
303
+ }
304
+ physicsSystem.AddConstraint(settings.Create(a, b));
305
+ for (const t of temps) jolt.destroy(t);
306
+ db.store.update(ids.get(r), { _joltJoint: true });
307
+ }
308
+ }
309
+
310
+ // Step on the fixed clock: 0..N steps of `fixedDt` this frame
311
+ // (decoupled from the render rate). On a stepping frame, snapshot
312
+ // the pose entering the final step into `_prevPosition`/`_prevRotation`
313
+ // first, so the pre-render interpolator can blend prev→current.
314
+ const clock = db.store.resources.physicsClock;
315
+ const steps = clock.steps;
316
+ if (steps === 0) return; // no sim time accrued — leave pose + snapshot intact
317
+
318
+ // Drive kinematic bodies to their authored pose: MoveKinematic derives
319
+ // the velocity to reach the target over the step, so the body pushes
320
+ // dynamics. (Author the pose however you like; the solver just follows.)
321
+ const dt = clock.fixedDt * steps;
322
+ const toFlip: Entity[] = []; // kinematic bodies whose bodyType became "dynamic" (ragdoll)
323
+ for (const arch of db.store.queryArchetypes(KINEMATIC, KINEMATIC_ONLY)) {
324
+ const ids = arch.columns.id, bt = arch.columns.bodyType;
325
+ const pos = arch.columns.position.getTypedArray(), ori = arch.columns.rotation.getTypedArray();
326
+ for (let r = 0; r < arch.rowCount; r++) {
327
+ const body = bodies.get(ids.get(r));
328
+ if (!body || !kPos || !kRot) continue;
329
+ if (bt.get(r) === "dynamic") { toFlip.push(ids.get(r)); continue; }
330
+ const r3 = r * 3, r4 = r * 4;
331
+ kPos.Set(pos[r3], pos[r3 + 1], pos[r3 + 2]);
332
+ kRot.Set(ori[r4], ori[r4 + 1], ori[r4 + 2], ori[r4 + 3]);
333
+ bi.MoveKinematic(body.GetID(), kPos, kRot, dt);
334
+ }
335
+ }
336
+ // Flip kinematic→dynamic (after the loop — migrating the row moves the typed
337
+ // arrays): become dynamic + gain the prev-pose snapshot, so it's simulated.
338
+ for (const id of toFlip) {
339
+ const body = bodies.get(id);
340
+ if (!body) continue;
341
+ bi.SetMotionType(body.GetID(), jolt.EMotionType_Dynamic, jolt.EActivation_Activate);
342
+ const rec = db.store.read(id) as { position: ArrayLike<number>; rotation: ArrayLike<number> };
343
+ db.store.update(id, {
344
+ _prevPosition: [rec.position[0], rec.position[1], rec.position[2]],
345
+ _prevRotation: [rec.rotation[0], rec.rotation[1], rec.rotation[2], rec.rotation[3]],
346
+ });
347
+ }
348
+ for (const arch of db.store.queryArchetypes(SNAPSHOT)) {
349
+ const bt = arch.columns.bodyType;
350
+ const pos = arch.columns.position.getTypedArray(), ori = arch.columns.rotation.getTypedArray();
351
+ const pp = arch.columns._prevPosition.getTypedArray(), pr = arch.columns._prevRotation.getTypedArray();
352
+ for (let r = 0; r < arch.rowCount; r++) {
353
+ if (!BodyType.isDynamic(bt.get(r))) continue;
354
+ const r3 = r * 3, r4 = r * 4;
355
+ pp[r3] = pos[r3]; pp[r3 + 1] = pos[r3 + 1]; pp[r3 + 2] = pos[r3 + 2];
356
+ pr[r4] = ori[r4]; pr[r4 + 1] = ori[r4 + 1]; pr[r4 + 2] = ori[r4 + 2]; pr[r4 + 3] = ori[r4 + 3];
357
+ }
358
+ }
359
+ for (let s = 0; s < steps; s++) joltInterface.Step(clock.fixedDt, 1);
360
+
361
+ // write the dynamic bodies' new pose + velocity back onto the canonical columns
362
+ for (const arch of db.store.queryArchetypes(RIGID)) {
363
+ const ids = arch.columns.id, bt = arch.columns.bodyType;
364
+ const pos = arch.columns.position.getTypedArray(), ori = arch.columns.rotation.getTypedArray();
365
+ const lv = arch.columns.linearVelocity.getTypedArray(), av = arch.columns.angularVelocity.getTypedArray();
366
+ for (let r = 0; r < arch.rowCount; r++) {
367
+ if (!BodyType.isDynamic(bt.get(r))) continue;
368
+ const body = bodies.get(ids.get(r));
369
+ if (!body) continue;
370
+ const t = body.GetPosition(), rot = body.GetRotation(), v = body.GetLinearVelocity(), w = body.GetAngularVelocity();
371
+ const r3 = r * 3, r4 = r * 4;
372
+ pos[r3] = t.GetX(); pos[r3 + 1] = t.GetY(); pos[r3 + 2] = t.GetZ();
373
+ ori[r4] = rot.GetX(); ori[r4 + 1] = rot.GetY(); ori[r4 + 2] = rot.GetZ(); ori[r4 + 3] = rot.GetW();
374
+ lv[r3] = v.GetX(); lv[r3 + 1] = v.GetY(); lv[r3 + 2] = v.GetZ();
375
+ av[r3] = w.GetX(); av[r3 + 1] = w.GetY(); av[r3 + 2] = w.GetZ();
376
+ }
377
+ }
378
+ };
379
+ },
380
+ },
381
+ },
382
+ });
@@ -0,0 +1,39 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { describe, it, expect } from "vitest";
4
+ import { runSolverBenchmark } from "./solver-benchmark.js";
5
+ import { rapierSolver } from "./rapier-solver-plugin.js";
6
+ import { joltSolver } from "./jolt-solver-plugin.js";
7
+
8
+ // Side-by-side performance + stability baseline of the reference solvers through
9
+ // the shared harness. See ./README.md for the Jolt-vs-Rapier guidance.
10
+ // npx vitest --run src/physics/solvers/rapier-jolt.benchmark.test.ts
11
+ describe("solver benchmarks", () => {
12
+ const OPTS = { bodies: 256, frames: 300 };
13
+
14
+ it("rapierSolver vs joltSolver — same dynamic pile", async () => {
15
+ const rap = await runSolverBenchmark(rapierSolver, OPTS);
16
+ const jol = await runSolverBenchmark(joltSolver, OPTS);
17
+ const line = (name: string, r: typeof rap) =>
18
+ `${name.padEnd(14)} ${r.msPerFrame.toFixed(3).padStart(8)} ms/frame · ${r.simFps.toFixed(0).padStart(5)} sim-fps · max ${r.maxFrameMs.toFixed(2).padStart(7)} ms · avgY ${r.avgY.toFixed(2).padStart(7)} · maxV ${r.maxSpeed.toFixed(1).padStart(7)} · sunk ${String(r.belowFloor).padStart(3)}`;
19
+ // eslint-disable-next-line no-console
20
+ console.log(`\n${OPTS.bodies} bodies × ${OPTS.frames} frames\n${line("rapierSolver", rap)}\n${line("joltSolver", jol)}\n`);
21
+ expect(rap.frames).toBe(300);
22
+ expect(jol.frames).toBe(300);
23
+ }, 90_000);
24
+
25
+ // The "many static, few dynamic" target: thousands of resting static bodies
26
+ // plus a handful of dynamics. The solver's per-frame sync must NOT re-scan
27
+ // every body — bodies already mirrored into the engine are tagged and
28
+ // excluded, so steady-state iteration is ~zero. (Measured win at 20k static:
29
+ // jolt 0.53→0.07 ms/frame, rapier 1.51→1.13.)
30
+ it("scales with many static bodies (sync excludes already-mirrored)", async () => {
31
+ const OPTS_S = { bodies: 64, staticBodies: 8000, frames: 120, warmupFrames: 60 };
32
+ const rap = await runSolverBenchmark(rapierSolver, OPTS_S);
33
+ const jol = await runSolverBenchmark(joltSolver, OPTS_S);
34
+ // eslint-disable-next-line no-console
35
+ console.log(`\n${OPTS_S.staticBodies} static + ${OPTS_S.bodies} dynamic\nrapierSolver ${rap.msPerFrame.toFixed(3)} ms/frame\njoltSolver ${jol.msPerFrame.toFixed(3)} ms/frame\n`);
36
+ expect(rap.frames).toBe(120);
37
+ expect(jol.frames).toBe(120);
38
+ }, 90_000);
39
+ });