@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,19 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { Schema } from "@adobe/data/schema";
4
+ import { schema } from "./schema.js";
5
+
6
+ /**
7
+ * How a joint constrains the two bodies it connects:
8
+ * fixed — rigidly locks them together (no relative motion).
9
+ * point — a ball/spherical joint: anchors coincide, free rotation (chains, ragdoll joints).
10
+ * hinge — a revolute joint: 1 rotational DOF about an axis, with optional angle limits (doors, elbows).
11
+ * cone — a swing-twist joint: the bone axis is bound to a cone (half-angle
12
+ * `jointSwingLimit`) around the reference axis, with a twist range
13
+ * (`jointMinLimit`/`jointMaxLimit`) about it — anatomical shoulder/hip
14
+ * limits for ragdolls. Full on Jolt (SwingTwist); Rapier's compat
15
+ * binding has no cone limit, so it approximates `cone` as a free `point`.
16
+ */
17
+ export type JointType = Schema.ToType<typeof schema>;
18
+
19
+ export * as JointType from "./public.js";
@@ -0,0 +1,3 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ export { schema } from "./schema.js";
@@ -0,0 +1,5 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { Schema } from "@adobe/data/schema";
4
+
5
+ export const schema = { type: "string", enum: ["fixed", "point", "hinge", "cone"] } as const satisfies Schema;
@@ -0,0 +1,27 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import type { Entity } from "@adobe/data/ecs";
4
+ import type { Vec3 } from "@adobe/data/math";
5
+ import type { JointType } from "./joint-type/joint-type.js";
6
+
7
+ /**
8
+ * One row of the `Joint` archetype — a constraint between two bodies, solved by
9
+ * whichever physics solver is active. Anchors are in each body's local frame;
10
+ * at rest the two anchor points coincide in world space (the joint location).
11
+ *
12
+ * `jointAxis` is the reference axis (body-A local) for `hinge` and `cone`,
13
+ * ignored otherwise. `jointMinLimit`/`jointMaxLimit` bound the hinge angle, or
14
+ * the `cone` twist angle, in radians (`min >= max` ⇒ free); `jointSwingLimit` is
15
+ * the `cone` swing half-angle.
16
+ */
17
+ export interface Joint {
18
+ jointType: JointType;
19
+ jointBodyA: Entity;
20
+ jointBodyB: Entity;
21
+ jointAnchorA: Vec3;
22
+ jointAnchorB: Vec3;
23
+ jointAxis: Vec3;
24
+ jointMinLimit: number;
25
+ jointMaxLimit: number;
26
+ jointSwingLimit: number;
27
+ }
@@ -0,0 +1,61 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { Database } from "@adobe/data/ecs";
4
+ import { core } from "../core/core-plugin.js";
5
+
6
+ /**
7
+ * Fixed-timestep physics clock — decouples the simulation rate from the render
8
+ * rate (Fiedler "fix your timestep"). Each render frame the accumulator absorbs
9
+ * the variable `frameTime.dt`; the solver then runs a whole number of fixed
10
+ * `fixedDt` steps (0, 1, or several), and `alpha` is the leftover fraction used
11
+ * to interpolate the rendered pose between the last two simulated states.
12
+ *
13
+ * Default 60 Hz; set another rate at init with `setFixedTimestep(hz)`.
14
+ */
15
+ export interface PhysicsClock {
16
+ /** Fixed simulation step length, seconds (default 1/60). */
17
+ readonly fixedDt: number;
18
+ /** Unsimulated time carried to the next frame, seconds (< fixedDt). */
19
+ readonly accumulator: number;
20
+ /** accumulator / fixedDt ∈ [0,1): render interpolation fraction prev→current. */
21
+ readonly alpha: number;
22
+ /** Whole steps the solver should run this frame (0..maxSubSteps). */
23
+ readonly steps: number;
24
+ /** Cap on steps/frame — prevents the "spiral of death" after a long stall. */
25
+ readonly maxSubSteps: number;
26
+ }
27
+
28
+ const DEFAULT: PhysicsClock = { fixedDt: 1 / 60, accumulator: 0, alpha: 0, steps: 0, maxSubSteps: 8 };
29
+
30
+ /**
31
+ * Provides the `physicsClock` resource and advances it once per render frame.
32
+ * Solver plugins extend this and run `physicsClock.steps` fixed steps; the
33
+ * interpolation system reads `physicsClock.alpha`. The advance runs first in the
34
+ * `physics` phase so solvers (scheduled `after: ["advancePhysicsClock"]`) see it.
35
+ */
36
+ export const physicsClock = Database.Plugin.create({
37
+ extends: core,
38
+ resources: {
39
+ physicsClock: { default: DEFAULT as PhysicsClock, transient: true },
40
+ },
41
+ transactions: {
42
+ /** Set the simulation rate (Hz). Call once at init; default is 60. */
43
+ setFixedTimestep(t, hz: number) {
44
+ t.resources.physicsClock = { ...t.resources.physicsClock, fixedDt: 1 / hz };
45
+ },
46
+ },
47
+ systems: {
48
+ advancePhysicsClock: {
49
+ schedule: { during: ["physics"] },
50
+ create: db => () => {
51
+ const c = db.store.resources.physicsClock;
52
+ const h = c.fixedDt;
53
+ // clamp the absorbed time to the step budget so a long stall (tab
54
+ // backgrounded, GC) can't queue hundreds of steps (spiral of death)
55
+ const acc = c.accumulator + Math.min(db.store.resources.frameTime.dt, h * c.maxSubSteps);
56
+ const steps = Math.min(Math.floor(acc / h), c.maxSubSteps);
57
+ db.store.resources.physicsClock = { ...c, accumulator: acc - steps * h, alpha: (acc - steps * h) / h, steps };
58
+ },
59
+ },
60
+ },
61
+ });
@@ -0,0 +1,55 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { describe, it, expect } from "vitest";
4
+ import { Database } from "@adobe/data/ecs";
5
+ import { physicsClock, type PhysicsClock } from "./physics-clock-plugin.js";
6
+
7
+ /** The accumulator turns a variable render dt into a whole number of fixed steps
8
+ * plus a leftover interpolation `alpha`, capped against the spiral of death. */
9
+ describe("physicsClock", () => {
10
+ // A created database carries a writable `store` (runtime invariant; not on the
11
+ // public type — same loose access the solver benchmark uses to drive frames).
12
+ interface ClockStore { resources: { physicsClock: PhysicsClock; frameTime: { now: number; dt: number; elapsed: number } } }
13
+
14
+ const make = () => {
15
+ const db = Database.create(physicsClock); // 60 Hz default
16
+ const store = (db as unknown as { store: ClockStore }).store;
17
+ const advance = (dt: number): PhysicsClock => {
18
+ store.resources.frameTime = { now: 0, dt, elapsed: 0 };
19
+ db.system.functions.advancePhysicsClock?.();
20
+ return store.resources.physicsClock;
21
+ };
22
+ return { db, advance };
23
+ };
24
+
25
+ it("matched render rate → exactly one step per frame, alpha ≈ 0", () => {
26
+ const c = make().advance(1 / 60);
27
+ expect(c.steps).toBe(1);
28
+ expect(c.alpha).toBeCloseTo(0);
29
+ });
30
+
31
+ it("render slower than sim → multiple steps per frame", () => {
32
+ expect(make().advance(1 / 30).steps).toBe(2); // two 1/60 steps fit one 1/30 frame
33
+ });
34
+
35
+ it("render faster than sim → 0-step frames that accumulate, alpha rising then resetting", () => {
36
+ const { advance } = make();
37
+ const a = advance(1 / 120); // half a step accrued
38
+ expect(a.steps).toBe(0);
39
+ expect(a.alpha).toBeCloseTo(0.5);
40
+ const b = advance(1 / 120); // now a full step is due
41
+ expect(b.steps).toBe(1);
42
+ expect(b.alpha).toBeCloseTo(0);
43
+ });
44
+
45
+ it("a long stall is capped at maxSubSteps (no spiral of death)", () => {
46
+ const c = make().advance(10); // 600 steps' worth of time
47
+ expect(c.steps).toBe(c.maxSubSteps);
48
+ });
49
+
50
+ it("setFixedTimestep changes the rate", () => {
51
+ const { db, advance } = make();
52
+ db.transactions.setFixedTimestep(30);
53
+ expect(advance(1 / 30).steps).toBe(1); // one 1/30 step per 1/30 frame
54
+ });
55
+ });
@@ -0,0 +1,73 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { Database } from "@adobe/data/ecs";
4
+ import { F32 } from "@adobe/data/schema";
5
+ import { Vec3, Quat } from "@adobe/data/math";
6
+ import { BodyType } from "./body/body-type/body-type.js";
7
+ import { ColliderShape } from "./body/collider-shape/collider-shape.js";
8
+ import type { ColliderMesh } from "./body/collider-mesh.js";
9
+ import { Material } from "../material/material.js";
10
+
11
+ /**
12
+ * The shared, solver-agnostic rigid-body data model — the seam every physics
13
+ * solver plugs into. It declares *only* authored/canonical state (no systems):
14
+ *
15
+ * bodyType, colliderShape, halfExtents, material — authored shape + role
16
+ * position, rotation, linearVelocity, angularVelocity — canonical live state
17
+ *
18
+ * A **solver plugin** `extends` this, may keep its own private `_`-prefixed
19
+ * internal state (broadphase, caches, GPU buffers), and each frame reads the
20
+ * authored state and writes back `position`/`rotation`/velocity for dynamic
21
+ * bodies. A renderer reads the canonical transforms, decoupled from which
22
+ * solver produced them — so solvers (`joltSolver`, `rapierSolver`; the GPU XPBD
23
+ * solver is shelved) are interchangeable over identical authored scenes.
24
+ *
25
+ * Two archetypes share these components:
26
+ * - **RigidBody** — `dynamic` or `kinematic` bodies that move; carries
27
+ * velocities and a `bodyType` discriminator.
28
+ * - **StaticCollider** — immovable colliders (floor, wall, ramp, scenery).
29
+ * No velocities (never integrated) and no `bodyType` (the archetype *is*
30
+ * the static classification) — a lean row for the bulk-static workload.
31
+ *
32
+ * `_prevPosition`/`_prevRotation` are derived (`_`-prefixed): the solver snapshots
33
+ * the pose *before* its final fixed step into them, so a render-rate interpolation
34
+ * pass can smoothly blend the previous → current simulated pose (see
35
+ * `physics-clock-plugin` + `interpolation-plugin`). Like `_worldMatrix`, they are
36
+ * *not* in the authored archetype — the solver migrates them onto each dynamic
37
+ * body the first time it mirrors it, so authors never supply derived state.
38
+ *
39
+ * Mass + inertia are derived per solver from shape + material (not stored here).
40
+ */
41
+ export const physicsData = Database.Plugin.create({
42
+ extends: Material.plugin, // brings the `material` reference component
43
+ components: {
44
+ bodyType: BodyType.schema,
45
+ colliderShape: ColliderShape.schema,
46
+ halfExtents: Vec3.schema, // box extents; sphere radius in .x
47
+ position: Vec3.schema,
48
+ rotation: Quat.schema, // unified with Node.rotation so a body renders directly
49
+ linearVelocity: Vec3.schema,
50
+ angularVelocity: Vec3.schema,
51
+ _prevPosition: Vec3.schema, // derived: pose before the last fixed step (render interpolation)
52
+ _prevRotation: Quat.schema,
53
+ // Bodies sharing the same non-zero collisionGroup do not collide with each
54
+ // other (they still collide with group 0 / the world) — e.g. a ragdoll's
55
+ // bones. 0 = default (collide with everything). Honored by both solvers
56
+ // (Rapier per-collider groups; Jolt a no-self-collide object layer). Note:
57
+ // it's currently binary (group 0 vs "some non-zero group"), not per-id masks.
58
+ collisionGroup: F32.schema,
59
+ // Authored collision geometry for shapes `halfExtents` can't describe.
60
+ // Runtime objects (variable length, no schema): the solver reads them once
61
+ // when it mirrors the body, the bridge once to build the render mesh.
62
+ convexPoints: { default: null as Float32Array | null }, // colliderShape "hull": point cloud → convex hull
63
+ colliderMesh: { default: null as ColliderMesh | null }, // colliderShape "mesh": static triangle soup
64
+ },
65
+ archetypes: {
66
+ RigidBody: ["bodyType", "colliderShape", "halfExtents", "material", "position", "rotation", "linearVelocity", "angularVelocity"],
67
+ StaticCollider: ["colliderShape", "halfExtents", "material", "position", "rotation"],
68
+ // A convex-hull body (dynamic / kinematic): authored as a point cloud.
69
+ ConvexBody: ["bodyType", "colliderShape", "halfExtents", "material", "position", "rotation", "linearVelocity", "angularVelocity", "convexPoints"],
70
+ // A static triangle-mesh collider (terrain / level geometry).
71
+ MeshCollider: ["colliderShape", "halfExtents", "material", "position", "rotation", "colliderMesh"],
72
+ },
73
+ });
@@ -0,0 +1,66 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import { describe, it, expect } from "vitest";
4
+ import { fitBoneCapsules, type SkinVertices } from "./fit-bone-capsules.js";
5
+
6
+ const IDENTITY_IBM = (n: number) => {
7
+ const m = new Float32Array(n * 16);
8
+ for (let j = 0; j < n; j++) { m[j * 16] = 1; m[j * 16 + 5] = 1; m[j * 16 + 10] = 1; m[j * 16 + 15] = 1; }
9
+ return m;
10
+ };
11
+
12
+ /** 8 corners of a box, all dominantly weighted to `joint`. */
13
+ function boxCorners(cx: number, cy: number, cz: number, hx: number, hy: number, hz: number, joint: number) {
14
+ const pos: number[] = [], jn: number[] = [], wt: number[] = [];
15
+ for (const sx of [-1, 1]) for (const sy of [-1, 1]) for (const sz of [-1, 1]) {
16
+ pos.push(cx + sx * hx, cy + sy * hy, cz + sz * hz);
17
+ jn.push(joint, 0, 0, 0); wt.push(1, 0, 0, 0);
18
+ }
19
+ return { pos, jn, wt };
20
+ }
21
+
22
+ const skinFrom = (...parts: { pos: number[]; jn: number[]; wt: number[] }[]): SkinVertices => ({
23
+ positions: new Float32Array(parts.flatMap(p => p.pos)),
24
+ joints: new Uint32Array(parts.flatMap(p => p.jn)),
25
+ weights: new Float32Array(parts.flatMap(p => p.wt)),
26
+ });
27
+
28
+ // rotate (0,1,0) by a quaternion
29
+ const rotateUp = (q: readonly number[]): [number, number, number] => {
30
+ const [x, y, z, w] = q;
31
+ return [2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x)];
32
+ };
33
+
34
+ describe("fitBoneCapsules", () => {
35
+ it("fits an X-elongated bone to an X-axis capsule of the right size", () => {
36
+ // box x∈[-2,2], y∈[-0.5,0.5], z∈[-0.4,0.4] → axis X, radius ½·max(1,0.8)=0.5, halfHeight 2−0.5=1.5
37
+ const caps = fitBoneCapsules({ jointCount: 1, inverseBindMatrices: IDENTITY_IBM(1), skin: skinFrom(boxCorners(0, 0, 0, 2, 0.5, 0.4, 0)) });
38
+ expect(caps).toHaveLength(1);
39
+ const c = caps[0];
40
+ expect(c.jointIndex).toBe(0);
41
+ expect(c.radius).toBeCloseTo(0.5);
42
+ expect(c.halfHeight).toBeCloseTo(1.5);
43
+ expect(c.offsetPosition[0]).toBeCloseTo(0);
44
+ // the capsule's local +Y, rotated by the offset, points along world X (the fit axis)
45
+ const up = rotateUp(c.offsetRotation);
46
+ expect(Math.abs(up[0])).toBeCloseTo(1);
47
+ expect(Math.abs(up[1])).toBeCloseTo(0);
48
+ });
49
+
50
+ it("fits one capsule per bone, grouping vertices by dominant weight", () => {
51
+ const caps = fitBoneCapsules({
52
+ jointCount: 2, inverseBindMatrices: IDENTITY_IBM(2),
53
+ skin: skinFrom(boxCorners(0, 0, 0, 1, 0.3, 0.3, 0), boxCorners(0, 5, 0, 0.3, 1, 0.3, 1)),
54
+ });
55
+ expect(caps.map(c => c.jointIndex).sort()).toEqual([0, 1]);
56
+ // bone 1 is Y-elongated → its capsule axis is Y (offset rotation ≈ identity)
57
+ const c1 = caps.find(c => c.jointIndex === 1)!;
58
+ expect(rotateUp(c1.offsetRotation)[1]).toBeCloseTo(1);
59
+ expect(c1.offsetPosition[1]).toBeCloseTo(5);
60
+ });
61
+
62
+ it("skips bones with too few assigned vertices", () => {
63
+ const sparse = { pos: [0, 0, 0, 1, 0, 0, 2, 0, 0], jn: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], wt: [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0] };
64
+ expect(fitBoneCapsules({ jointCount: 1, inverseBindMatrices: IDENTITY_IBM(1), skin: skinFrom(sparse) })).toHaveLength(0);
65
+ });
66
+ });
@@ -0,0 +1,106 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+
3
+ import type { Vec3, Quat } from "@adobe/data/math";
4
+
5
+ /**
6
+ * Fits one capsule collider to each significant bone of a skinned mesh — the
7
+ * per-bone colliders a ragdoll needs (you can't trimesh a deforming skin). Each
8
+ * vertex is assigned to the bone it's *most* weighted to; that bone's vertices
9
+ * are pushed into the bone's bind-local frame (via the joint's inverse-bind
10
+ * matrix) and a capsule is fitted to them: the longest local axis becomes the
11
+ * capsule axis, the perpendicular spread its radius.
12
+ *
13
+ * The result is expressed as a bone-local offset (`offsetPosition` /
14
+ * `offsetRotation`, which orients the Y-aligned capsule onto the fitted axis)
15
+ * plus dimensions — so the capsule's world pose each frame is just
16
+ * `jointWorldMatrix · offset`, tracking the animated skeleton.
17
+ */
18
+
19
+ /** Skinned vertices in mesh (bind) space: `positions` (xyz triples), `joints`
20
+ * (4 joint indices/vertex), `weights` (4 weights/vertex). */
21
+ export interface SkinVertices {
22
+ positions: Float32Array;
23
+ joints: Uint32Array;
24
+ weights: Float32Array;
25
+ }
26
+
27
+ export interface FitBoneCapsulesInput {
28
+ jointCount: number;
29
+ /** glTF inverse-bind matrices, column-major, `jointCount × 16`. */
30
+ inverseBindMatrices: Float32Array;
31
+ skin: SkinVertices;
32
+ /** A vertex joins a bone only if its dominant weight ≥ this (default 0.5). */
33
+ minWeight?: number;
34
+ /** Bones with fewer assigned vertices than this get no capsule (default 6). */
35
+ minVertices?: number;
36
+ }
37
+
38
+ export interface BoneCapsule {
39
+ jointIndex: number;
40
+ offsetPosition: Vec3; // capsule centre, bone-bind-local
41
+ offsetRotation: Quat; // orients the Y-aligned capsule onto the fitted axis, bone-bind-local
42
+ radius: number;
43
+ halfHeight: number; // half-length of the cylindrical section
44
+ }
45
+
46
+ /** Transform a point by a column-major 4×4 matrix (slice `o..o+16`), into `out`. */
47
+ function transformPoint(m: Float32Array, o: number, x: number, y: number, z: number, out: [number, number, number]): void {
48
+ out[0] = m[o] * x + m[o + 4] * y + m[o + 8] * z + m[o + 12];
49
+ out[1] = m[o + 1] * x + m[o + 5] * y + m[o + 9] * z + m[o + 13];
50
+ out[2] = m[o + 2] * x + m[o + 6] * y + m[o + 10] * z + m[o + 14];
51
+ }
52
+
53
+ /** Shortest-arc quaternion rotating +Y onto unit vector `b`. */
54
+ function quatFromY(bx: number, by: number, bz: number): Quat {
55
+ if (by > 0.99999) return [0, 0, 0, 1]; // already +Y
56
+ if (by < -0.99999) return [0, 0, 1, 0]; // 180° (about Z) onto −Y
57
+ // half-vector method: h = normalize((0,1,0) + b); q = ((0,1,0)×h, (0,1,0)·h)
58
+ const hx = bx, hy = 1 + by, hz = bz;
59
+ const hl = Math.hypot(hx, hy, hz) || 1;
60
+ const nx = hx / hl, ny = hy / hl, nz = hz / hl;
61
+ // (0,1,0) × (nx,ny,nz) = (nz·? ) → cross = (1*nz - 0*ny, 0*nx - 0*nz, 0*ny - 1*nx) = (nz, 0, -nx)
62
+ return [nz, 0, -nx, ny];
63
+ }
64
+
65
+ export function fitBoneCapsules(input: FitBoneCapsulesInput): BoneCapsule[] {
66
+ const { jointCount, inverseBindMatrices: ibm, skin } = input;
67
+ const minWeight = input.minWeight ?? 0.5;
68
+ const minVertices = input.minVertices ?? 6;
69
+ const vertexCount = skin.positions.length / 3;
70
+
71
+ // bone-local AABB per joint (min/max), accumulated over its dominant vertices
72
+ const min = new Float32Array(jointCount * 3).fill(Infinity);
73
+ const max = new Float32Array(jointCount * 3).fill(-Infinity);
74
+ const count = new Uint32Array(jointCount);
75
+ const p: [number, number, number] = [0, 0, 0];
76
+
77
+ for (let v = 0; v < vertexCount; v++) {
78
+ // dominant bone = the vertex's max-weight joint
79
+ let best = 0, bestW = -1;
80
+ for (let k = 0; k < 4; k++) { const w = skin.weights[v * 4 + k]; if (w > bestW) { bestW = w; best = skin.joints[v * 4 + k]; } }
81
+ if (bestW < minWeight || best >= jointCount) continue;
82
+ transformPoint(ibm, best * 16, skin.positions[v * 3], skin.positions[v * 3 + 1], skin.positions[v * 3 + 2], p);
83
+ const b = best * 3;
84
+ if (p[0] < min[b]) min[b] = p[0]; if (p[0] > max[b]) max[b] = p[0];
85
+ if (p[1] < min[b + 1]) min[b + 1] = p[1]; if (p[1] > max[b + 1]) max[b + 1] = p[1];
86
+ if (p[2] < min[b + 2]) min[b + 2] = p[2]; if (p[2] > max[b + 2]) max[b + 2] = p[2];
87
+ count[best]++;
88
+ }
89
+
90
+ const out: BoneCapsule[] = [];
91
+ for (let j = 0; j < jointCount; j++) {
92
+ if (count[j] < minVertices) continue;
93
+ const b = j * 3;
94
+ const ex = max[b] - min[b], ey = max[b + 1] - min[b + 1], ez = max[b + 2] - min[b + 2];
95
+ // longest extent = capsule axis; the other two give the (bounding) radius
96
+ let axis: 0 | 1 | 2 = 0, axisExtent = ex, r1 = ey, r2 = ez;
97
+ if (ey >= ex && ey >= ez) { axis = 1; axisExtent = ey; r1 = ex; r2 = ez; }
98
+ else if (ez >= ex && ez >= ey) { axis = 2; axisExtent = ez; r1 = ex; r2 = ey; }
99
+ const radius = Math.max(r1, r2) / 2 || 1e-3;
100
+ const halfHeight = Math.max(0, axisExtent / 2 - radius);
101
+ const offsetPosition: Vec3 = [(min[b] + max[b]) / 2, (min[b + 1] + max[b + 1]) / 2, (min[b + 2] + max[b + 2]) / 2];
102
+ const offsetRotation = quatFromY(axis === 0 ? 1 : 0, axis === 1 ? 1 : 0, axis === 2 ? 1 : 0);
103
+ out.push({ jointIndex: j, offsetPosition, offsetRotation, radius, halfHeight });
104
+ }
105
+ return out;
106
+ }
@@ -0,0 +1,63 @@
1
+ # Physics solvers
2
+
3
+ Rigid-body solvers that plug into the shared `physicsData` seam. A solver reads
4
+ the authored `RigidBody` + `StaticCollider` components and writes back
5
+ `position`/`rotation`/velocity for dynamic bodies each frame, so the **same
6
+ scene runs unchanged on any solver** (`Database.Plugin.combine(scene, solver)`).
7
+
8
+ Two production-grade solvers ship, both compiled to WASM and wired identically:
9
+
10
+ | solver | engine | license |
11
+ | --- | --- | --- |
12
+ | `joltSolver` | Jolt Physics (Jorrit Rouwe) | MIT |
13
+ | `rapierSolver` | Rapier (dimforge) | Apache-2.0 |
14
+
15
+ Both are **opt-in**: the engine packages are regular dependencies, but with
16
+ `sideEffects: false` a bundler tree-shakes the solver (and its WASM) out unless
17
+ you actually import it. (The from-scratch CPU-XPBD solver was removed — it was
18
+ ~10–15× slower and unstable on dense piles; these engines supersede it.)
19
+
20
+ ## Which to use
21
+
22
+ **Default to `joltSolver`.** It's the most stable, it sleeps inert bodies (so
23
+ "many static, few dynamic" scenes cost almost nothing), and it handles deep/dense
24
+ stacks cleanly.
25
+
26
+ **Choose `rapierSolver` only when** the scene is dominated by *many
27
+ simultaneously-active dynamic bodies* most of the time **and** tight stability
28
+ isn't critical — that's the one regime where Rapier's per-step dynamic
29
+ throughput wins.
30
+
31
+ ## Measured baseline
32
+
33
+ Headless harness (`runSolverBenchmark`), fixed 1/60 s timestep. Stability shown
34
+ as end-state mean height / peak speed (a tight settle is low/low).
35
+
36
+ **256 mixed dynamic bodies dropped into a walled bin (300 frames):**
37
+
38
+ | solver | ms/frame | sim-fps | stability (avgY · maxV) |
39
+ | --- | --- | --- | --- |
40
+ | `rapierSolver` | **0.90** | 1117 | −1.3 · 57 |
41
+ | `joltSolver` | 1.57 | 638 | **−0.4 · 47** (tighter) |
42
+
43
+ → Rapier ~1.7× faster on a busy dynamic pile; Jolt settles tighter.
44
+
45
+ **8000 static + 64 dynamic (the "many static, few dynamic" target):**
46
+
47
+ | solver | ms/frame |
48
+ | --- | --- |
49
+ | `joltSolver` | **0.196** |
50
+ | `rapierSolver` | 0.344 |
51
+
52
+ → Jolt ~1.75× faster — it sleeps the inert statics to near-zero step cost.
53
+
54
+ Reproduce / track regressions: `npx vitest --run
55
+ src/physics/solvers/rapier-jolt.benchmark.test.ts`. Numbers are post the
56
+ sync tag-exclude optimization (see this package's `CLAUDE.md`).
57
+
58
+ ## Adding another solver
59
+
60
+ Implement the seam: extend `combine(physicsData, core)`, mirror new bodies into
61
+ the engine in the `physics` phase (tag + `exclude` so the sync is O(new) — see
62
+ the existing plugins and `CLAUDE.md`), step, and write the dynamic transforms
63
+ back via `getTypedArray()`. Benchmark it through `runSolverBenchmark` to compare.