@adobe/data-gpu 0.9.75 → 0.9.76

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 (383) hide show
  1. package/CLAUDE.md +9 -0
  2. package/README.md +36 -0
  3. package/dist/core/core-plugin.d.ts +1 -1
  4. package/dist/core/public.d.ts +2 -0
  5. package/dist/core/public.js +4 -0
  6. package/dist/core/public.js.map +1 -0
  7. package/dist/graphics/animation/animation-data-plugin.d.ts +8 -0
  8. package/dist/graphics/animation/animation-plugin.d.ts +10 -2
  9. package/dist/graphics/camera/camera-plugin.d.ts +3 -3
  10. package/dist/graphics/camera/orbit/attach-orbit-drag.d.ts +1 -21
  11. package/dist/graphics/camera/orbit/attach-orbit-drag.js +0 -10
  12. package/dist/graphics/camera/orbit/attach-orbit-drag.js.map +1 -1
  13. package/dist/graphics/camera/orbit/orbit-data-plugin.d.ts +6 -6
  14. package/dist/graphics/camera/orbit/orbit-data-plugin.js +1 -1
  15. package/dist/graphics/camera/orbit/orbit-data-plugin.js.map +1 -1
  16. package/dist/graphics/camera/orbit/orbit-drag-service.d.ts +11 -0
  17. package/dist/graphics/camera/orbit/orbit-drag-service.js +3 -0
  18. package/dist/graphics/camera/orbit/orbit-drag-service.js.map +1 -0
  19. package/dist/graphics/camera/orbit/orbit-plugin.d.ts +6 -6
  20. package/dist/graphics/camera/orbit/orbit-system-plugin.d.ts +8 -8
  21. package/dist/graphics/camera/orbit/orbit-system-plugin.js +6 -9
  22. package/dist/graphics/camera/orbit/orbit-system-plugin.js.map +1 -1
  23. package/dist/graphics/camera/orbit/orbit.d.ts +5 -5
  24. package/dist/graphics/camera/orbit/public.d.ts +2 -2
  25. package/dist/graphics/camera/orbit/public.js +2 -1
  26. package/dist/graphics/camera/orbit/public.js.map +1 -1
  27. package/dist/graphics/graphics-plugin.d.ts +1 -1
  28. package/dist/graphics/index.d.ts +1 -0
  29. package/dist/graphics/index.js +3 -0
  30. package/dist/graphics/index.js.map +1 -0
  31. package/dist/graphics/picking/picking-plugin.d.ts +9871 -1912
  32. package/dist/graphics/picking/picking-plugin.js +3 -3
  33. package/dist/graphics/picking/picking-plugin.js.map +1 -1
  34. package/dist/graphics/public.d.ts +38 -0
  35. package/dist/graphics/public.js +40 -0
  36. package/dist/graphics/public.js.map +1 -0
  37. package/dist/graphics/rendering/bone-collider-plugin.d.ts +2967 -486
  38. package/dist/graphics/rendering/bone-collider-plugin.js +13 -12
  39. package/dist/graphics/rendering/bone-collider-plugin.js.map +1 -1
  40. package/dist/graphics/rendering/display-transform-plugin.d.ts +2 -0
  41. package/dist/graphics/rendering/display-transform-plugin.js +2 -2
  42. package/dist/graphics/rendering/display-transform-plugin.js.map +1 -1
  43. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.d.ts +2857 -403
  44. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.js +9 -9
  45. package/dist/graphics/rendering/ibl-render/ibl-render-plugin.js.map +1 -1
  46. package/dist/graphics/rendering/interpolation-plugin.d.ts +1040 -156
  47. package/dist/graphics/rendering/jolt-ragdoll-plugin.d.ts +3017 -538
  48. package/dist/graphics/rendering/jolt-ragdoll-plugin.js +6 -6
  49. package/dist/graphics/rendering/jolt-ragdoll-plugin.js.map +1 -1
  50. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu-plugin.d.ts +1123 -0
  51. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu-plugin.js +79 -0
  52. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu-plugin.js.map +1 -0
  53. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu.test.d.ts +1 -0
  54. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu.test.js +18 -0
  55. package/dist/graphics/rendering/material-palette-gpu/material-palette-gpu.test.js.map +1 -0
  56. package/dist/graphics/rendering/material-palette-gpu/material-palette.d.ts +25 -0
  57. package/dist/graphics/rendering/material-palette-gpu/material-palette.js +27 -0
  58. package/dist/graphics/rendering/material-palette-gpu/material-palette.js.map +1 -0
  59. package/dist/graphics/rendering/material-palette-gpu/palette-bind-group.d.ts +3 -0
  60. package/dist/graphics/rendering/material-palette-gpu/palette-bind-group.js +22 -0
  61. package/dist/graphics/rendering/material-palette-gpu/palette-bind-group.js.map +1 -0
  62. package/dist/graphics/rendering/model-collider-plugin.d.ts +2903 -663
  63. package/dist/graphics/rendering/model-collider-plugin.js +11 -34
  64. package/dist/graphics/rendering/model-collider-plugin.js.map +1 -1
  65. package/dist/graphics/rendering/pbr-core-plugin.d.ts +16 -8
  66. package/dist/graphics/rendering/pbr-core-plugin.js +16 -19
  67. package/dist/graphics/rendering/pbr-core-plugin.js.map +1 -1
  68. package/dist/graphics/rendering/pbr-render/pbr-factor-render-plugin.d.ts +3514 -0
  69. package/dist/graphics/rendering/pbr-render/pbr-factor-render-plugin.js +189 -0
  70. package/dist/graphics/rendering/pbr-render/pbr-factor-render-plugin.js.map +1 -0
  71. package/dist/graphics/rendering/pbr-render/pbr-factor-shader.wgsl.d.ts +7 -0
  72. package/dist/graphics/rendering/pbr-render/pbr-factor-shader.wgsl.js +124 -0
  73. package/dist/graphics/rendering/pbr-render/pbr-factor-shader.wgsl.js.map +1 -0
  74. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.d.ts +769 -571
  75. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.js +98 -79
  76. package/dist/graphics/rendering/pbr-render/physics-bridge-plugin.js.map +1 -1
  77. package/dist/graphics/rendering/pbr-render/primitive-render-shared.d.ts +43 -0
  78. package/dist/graphics/rendering/pbr-render/primitive-render-shared.js +59 -0
  79. package/dist/graphics/rendering/pbr-render/primitive-render-shared.js.map +1 -0
  80. package/dist/graphics/rendering/skinning/skinning-plugin.d.ts +2930 -270
  81. package/dist/graphics/rendering/skinning/skinning-plugin.js +19 -40
  82. package/dist/graphics/rendering/skinning/skinning-plugin.js.map +1 -1
  83. package/dist/graphics/scene/model/geometry/public.d.ts +1 -0
  84. package/dist/graphics/scene/model/mesh/mesh.d.ts +13 -0
  85. package/dist/graphics/scene/model/mesh/mesh.js +3 -0
  86. package/dist/graphics/scene/model/mesh/mesh.js.map +1 -0
  87. package/dist/graphics/scene/model/mesh/public.d.ts +1 -0
  88. package/dist/graphics/scene/model/mesh/public.js +3 -0
  89. package/dist/graphics/scene/model/mesh/public.js.map +1 -0
  90. package/dist/graphics/scene/model/mesh-plugin.d.ts +5177 -0
  91. package/dist/graphics/scene/model/mesh-plugin.js +87 -0
  92. package/dist/graphics/scene/model/mesh-plugin.js.map +1 -0
  93. package/dist/graphics/scene/model/model-loader-plugin.d.ts +2728 -295
  94. package/dist/graphics/scene/model/model-loader-plugin.js +24 -42
  95. package/dist/graphics/scene/model/model-loader-plugin.js.map +1 -1
  96. package/dist/graphics/scene/model/model-plugin.d.ts +1 -352
  97. package/dist/graphics/scene/model/model-plugin.js +1 -37
  98. package/dist/graphics/scene/model/model-plugin.js.map +1 -1
  99. package/dist/graphics/scene/model/model.d.ts +2 -6
  100. package/dist/graphics/scene/model/model.js.map +1 -1
  101. package/dist/graphics/scene/model/public.d.ts +1 -1
  102. package/dist/graphics/scene/model/public.js +2 -1
  103. package/dist/graphics/scene/model/public.js.map +1 -1
  104. package/dist/graphics/scene/model/shape/bounds-from-shape-mesh.d.ts +4 -0
  105. package/dist/graphics/scene/model/shape/bounds-from-shape-mesh.js +25 -0
  106. package/dist/graphics/scene/model/shape/bounds-from-shape-mesh.js.map +1 -0
  107. package/dist/graphics/scene/model/shape/shape-geometry-plugin.d.ts +233 -386
  108. package/dist/graphics/scene/model/shape/shape-geometry-plugin.js +87 -18
  109. package/dist/graphics/scene/model/shape/shape-geometry-plugin.js.map +1 -1
  110. package/dist/graphics/scene/model/shape/shape-spec.d.ts +17 -0
  111. package/dist/graphics/scene/model/shape/shape-spec.js +3 -0
  112. package/dist/graphics/scene/model/shape/shape-spec.js.map +1 -0
  113. package/dist/graphics/scene/model/world-bounds-plugin.d.ts +2670 -245
  114. package/dist/graphics/scene/model/world-bounds-plugin.js +6 -25
  115. package/dist/graphics/scene/model/world-bounds-plugin.js.map +1 -1
  116. package/dist/graphics/scene/node/node-data-plugin.d.ts +15 -4
  117. package/dist/graphics/scene/node/node-data-plugin.js +12 -5
  118. package/dist/graphics/scene/node/node-data-plugin.js.map +1 -1
  119. package/dist/graphics/scene/node/node-data-plugin.test.d.ts +1 -0
  120. package/dist/graphics/scene/node/node-data-plugin.test.js +40 -0
  121. package/dist/graphics/scene/node/node-data-plugin.test.js.map +1 -0
  122. package/dist/graphics/scene/node/node-plugin.d.ts +8 -1
  123. package/dist/graphics/scene/node/transform-plugin.d.ts +8 -1
  124. package/dist/graphics/scene/scene-plugin.d.ts +2353 -100
  125. package/dist/graphics/scene/scene-plugin.js +3 -3
  126. package/dist/graphics/scene/scene-plugin.js.map +1 -1
  127. package/dist/graphics/scene/scene-uniforms/scene-uniforms-plugin.d.ts +3 -3
  128. package/dist/index.d.ts +1 -53
  129. package/dist/index.js +1 -54
  130. package/dist/index.js.map +1 -1
  131. package/dist/material/assemble-material-row.d.ts +4 -0
  132. package/dist/material/assemble-material-row.js +22 -0
  133. package/dist/material/assemble-material-row.js.map +1 -0
  134. package/dist/material/definitions.d.ts +833 -0
  135. package/dist/material/definitions.js +423 -0
  136. package/dist/material/definitions.js.map +1 -0
  137. package/dist/material/emission-mode.d.ts +8 -0
  138. package/dist/material/emission-mode.js +9 -0
  139. package/dist/material/emission-mode.js.map +1 -0
  140. package/dist/material/index.d.ts +1 -0
  141. package/dist/material/index.js +3 -0
  142. package/dist/material/index.js.map +1 -0
  143. package/dist/material/json/from-json-string.d.ts +2 -0
  144. package/dist/material/json/from-json-string.js +12 -0
  145. package/dist/material/json/from-json-string.js.map +1 -0
  146. package/dist/material/json/from-json.d.ts +10 -0
  147. package/dist/material/json/from-json.js +16 -0
  148. package/dist/material/json/from-json.js.map +1 -0
  149. package/dist/material/json/from-json.test.d.ts +1 -0
  150. package/dist/material/json/from-json.test.js +46 -0
  151. package/dist/material/json/from-json.test.js.map +1 -0
  152. package/dist/material/json/is-properties-json.d.ts +2 -0
  153. package/dist/material/json/is-properties-json.js +65 -0
  154. package/dist/material/json/is-properties-json.js.map +1 -0
  155. package/dist/material/json/library-json.d.ts +3 -0
  156. package/dist/material/json/library-json.js +2 -0
  157. package/dist/material/json/library-json.js.map +1 -0
  158. package/dist/material/json/load-json.d.ts +7 -0
  159. package/dist/material/json/load-json.js +10 -0
  160. package/dist/material/json/load-json.js.map +1 -0
  161. package/dist/material/json/properties-json.d.ts +25 -0
  162. package/dist/material/json/properties-json.js +2 -0
  163. package/dist/material/json/properties-json.js.map +1 -0
  164. package/dist/material/json/public.d.ts +9 -0
  165. package/dist/material/json/public.js +6 -0
  166. package/dist/material/json/public.js.map +1 -0
  167. package/dist/material/json/to-definition.d.ts +5 -0
  168. package/dist/material/json/to-definition.js +65 -0
  169. package/dist/material/json/to-definition.js.map +1 -0
  170. package/dist/material/material-by-name-lookup.d.ts +11 -0
  171. package/dist/material/material-by-name-lookup.js +3 -0
  172. package/dist/material/material-by-name-lookup.js.map +1 -0
  173. package/dist/material/material-defaults.d.ts +23 -0
  174. package/dist/material/material-defaults.js +25 -0
  175. package/dist/material/material-defaults.js.map +1 -0
  176. package/dist/material/material-definition.d.ts +3 -0
  177. package/dist/material/material-definition.js +2 -0
  178. package/dist/material/material-definition.js.map +1 -0
  179. package/dist/material/material-name.d.ts +2 -0
  180. package/dist/material/material-name.js +2 -0
  181. package/dist/material/material-name.js.map +1 -0
  182. package/dist/material/material-plugin.d.ts +891 -22
  183. package/dist/material/material-plugin.js +46 -21
  184. package/dist/material/material-plugin.js.map +1 -1
  185. package/dist/material/material-plugin.test.d.ts +1 -0
  186. package/dist/material/material-plugin.test.js +87 -0
  187. package/dist/material/material-plugin.test.js.map +1 -0
  188. package/dist/material/material.d.ts +27 -29
  189. package/dist/material/material.js +0 -1
  190. package/dist/material/material.js.map +1 -1
  191. package/dist/material/public.d.ts +12 -2
  192. package/dist/material/public.js +12 -2
  193. package/dist/material/public.js.map +1 -1
  194. package/dist/material/require-material.d.ts +4 -0
  195. package/dist/material/require-material.js +10 -0
  196. package/dist/material/require-material.js.map +1 -0
  197. package/dist/material/standard-material-names.d.ts +2 -0
  198. package/dist/material/standard-material-names.js +4 -0
  199. package/dist/material/standard-material-names.js.map +1 -0
  200. package/dist/material/standard-materials.d.ts +1 -1
  201. package/dist/material/standard-materials.js +17 -24
  202. package/dist/material/standard-materials.js.map +1 -1
  203. package/dist/material/stress-strain-curve/create.d.ts +8 -0
  204. package/dist/material/stress-strain-curve/create.js +2 -0
  205. package/dist/material/stress-strain-curve/create.js.map +1 -0
  206. package/dist/material/stress-strain-curve/public.d.ts +2 -0
  207. package/dist/material/stress-strain-curve/public.js +3 -0
  208. package/dist/material/stress-strain-curve/public.js.map +1 -0
  209. package/dist/material/stress-strain-curve/schema.d.ts +52 -0
  210. package/dist/material/stress-strain-curve/schema.js +19 -0
  211. package/dist/material/stress-strain-curve/schema.js.map +1 -0
  212. package/dist/material/stress-strain-curve/schema.test.d.ts +1 -0
  213. package/dist/material/stress-strain-curve/schema.test.js +18 -0
  214. package/dist/material/stress-strain-curve/schema.test.js.map +1 -0
  215. package/dist/material/stress-strain-curve/stress-strain-curve.d.ts +4 -0
  216. package/dist/material/stress-strain-curve/stress-strain-curve.js +2 -0
  217. package/dist/material/stress-strain-curve/stress-strain-curve.js.map +1 -0
  218. package/dist/physics/body/collider-shape/mass-from-volume.d.ts +2 -0
  219. package/dist/physics/body/collider-shape/mass-from-volume.js +4 -0
  220. package/dist/physics/body/collider-shape/mass-from-volume.js.map +1 -0
  221. package/dist/physics/body/collider-shape/mass-from-volume.test.d.ts +1 -0
  222. package/dist/physics/body/collider-shape/mass-from-volume.test.js +8 -0
  223. package/dist/physics/body/collider-shape/mass-from-volume.test.js.map +1 -0
  224. package/dist/physics/collider-primitive-render-archetype.d.ts +2 -0
  225. package/dist/physics/collider-primitive-render-archetype.js +3 -0
  226. package/dist/physics/collider-primitive-render-archetype.js.map +1 -0
  227. package/dist/physics/collider-primitive-render-archetypes.d.ts +2 -0
  228. package/dist/physics/collider-primitive-render-archetypes.js +9 -0
  229. package/dist/physics/collider-primitive-render-archetypes.js.map +1 -0
  230. package/dist/physics/index.d.ts +1 -0
  231. package/dist/physics/index.js +3 -0
  232. package/dist/physics/index.js.map +1 -0
  233. package/dist/physics/is-voxel-shape-physics-pending.d.ts +3 -0
  234. package/dist/physics/is-voxel-shape-physics-pending.js +7 -0
  235. package/dist/physics/is-voxel-shape-physics-pending.js.map +1 -0
  236. package/dist/physics/physics-clock/physics-clock.d.ts +15 -0
  237. package/dist/physics/physics-clock/physics-clock.js +3 -0
  238. package/dist/physics/physics-clock/physics-clock.js.map +1 -0
  239. package/dist/physics/physics-clock-plugin.d.ts +2 -22
  240. package/dist/physics/physics-clock-plugin.js +0 -2
  241. package/dist/physics/physics-clock-plugin.js.map +1 -1
  242. package/dist/physics/physics-clock.test.js.map +1 -1
  243. package/dist/physics/physics-data-plugin.d.ts +889 -13
  244. package/dist/physics/physics-data-plugin.js +8 -6
  245. package/dist/physics/physics-data-plugin.js.map +1 -1
  246. package/dist/physics/public.d.ts +21 -0
  247. package/dist/physics/public.js +23 -0
  248. package/dist/physics/public.js.map +1 -0
  249. package/dist/physics/ragdoll/bone-capsule.d.ts +8 -0
  250. package/dist/physics/ragdoll/bone-capsule.js +3 -0
  251. package/dist/physics/ragdoll/bone-capsule.js.map +1 -0
  252. package/dist/physics/ragdoll/fit-bone-capsules-input.d.ts +11 -0
  253. package/dist/physics/ragdoll/fit-bone-capsules-input.js +3 -0
  254. package/dist/physics/ragdoll/fit-bone-capsules-input.js.map +1 -0
  255. package/dist/physics/ragdoll/fit-bone-capsules.d.ts +2 -38
  256. package/dist/physics/ragdoll/fit-bone-capsules.js +13 -0
  257. package/dist/physics/ragdoll/fit-bone-capsules.js.map +1 -1
  258. package/dist/physics/ragdoll/fit-bone-capsules.test.js.map +1 -1
  259. package/dist/physics/ragdoll/skin-vertices.d.ts +6 -0
  260. package/dist/physics/ragdoll/skin-vertices.js +3 -0
  261. package/dist/physics/ragdoll/skin-vertices.js.map +1 -0
  262. package/dist/physics/rigid-body-components.d.ts +2 -0
  263. package/dist/physics/rigid-body-components.js +13 -0
  264. package/dist/physics/rigid-body-components.js.map +1 -0
  265. package/dist/physics/solvers/jolt-solver-plugin.d.ts +918 -41
  266. package/dist/physics/solvers/jolt-solver-plugin.js +19 -3
  267. package/dist/physics/solvers/jolt-solver-plugin.js.map +1 -1
  268. package/dist/physics/solvers/rapier-solver-plugin.d.ts +918 -41
  269. package/dist/physics/solvers/rapier-solver-plugin.js +7 -2
  270. package/dist/physics/solvers/rapier-solver-plugin.js.map +1 -1
  271. package/dist/physics/solvers/solver-benchmark-options.d.ts +14 -0
  272. package/dist/physics/solvers/solver-benchmark-options.js +3 -0
  273. package/dist/physics/solvers/solver-benchmark-options.js.map +1 -0
  274. package/dist/physics/solvers/solver-benchmark-result.d.ts +15 -0
  275. package/dist/physics/solvers/solver-benchmark-result.js +3 -0
  276. package/dist/physics/solvers/solver-benchmark-result.js.map +1 -0
  277. package/dist/physics/solvers/solver-benchmark.d.ts +2 -43
  278. package/dist/physics/solvers/solver-benchmark.js.map +1 -1
  279. package/dist/physics/static-collider-components.d.ts +2 -0
  280. package/dist/physics/static-collider-components.js +10 -0
  281. package/dist/physics/static-collider-components.js.map +1 -0
  282. package/package.json +14 -2
  283. package/src/core/public.ts +4 -0
  284. package/src/graphics/camera/orbit/attach-orbit-drag.ts +7 -27
  285. package/src/graphics/camera/orbit/orbit-data-plugin.ts +1 -1
  286. package/src/graphics/camera/orbit/orbit-drag-service.ts +13 -0
  287. package/src/graphics/camera/orbit/orbit-system-plugin.ts +6 -9
  288. package/src/graphics/camera/orbit/orbit.ts +5 -5
  289. package/src/graphics/camera/orbit/public.ts +2 -2
  290. package/src/graphics/index.ts +3 -0
  291. package/src/graphics/picking/picking-plugin.ts +4 -4
  292. package/src/graphics/public.ts +40 -0
  293. package/src/graphics/rendering/bone-collider-plugin.ts +16 -12
  294. package/src/graphics/rendering/display-transform-plugin.ts +2 -2
  295. package/src/graphics/rendering/ibl-render/ibl-render-plugin.ts +9 -9
  296. package/src/graphics/rendering/interpolation.test.ts +1 -1
  297. package/src/graphics/rendering/jolt-ragdoll-plugin.ts +11 -7
  298. package/src/graphics/rendering/material-palette-gpu/material-palette-gpu-plugin.ts +86 -0
  299. package/src/graphics/rendering/material-palette-gpu/material-palette-gpu.test.ts +20 -0
  300. package/src/graphics/rendering/material-palette-gpu/material-palette.ts +41 -0
  301. package/src/graphics/rendering/material-palette-gpu/palette-bind-group.ts +24 -0
  302. package/src/graphics/rendering/model-collider-plugin.ts +19 -35
  303. package/src/graphics/rendering/pbr-core-plugin.ts +16 -19
  304. package/src/graphics/rendering/pbr-render/{pbr-render-plugin.ts → pbr-factor-render-plugin.ts} +60 -111
  305. package/src/graphics/rendering/pbr-render/{pbr-array-shader.wgsl.ts → pbr-factor-shader.wgsl.ts} +19 -40
  306. package/src/graphics/rendering/pbr-render/physics-bridge-plugin.ts +95 -69
  307. package/src/graphics/rendering/pbr-render/primitive-render-shared.ts +76 -0
  308. package/src/graphics/rendering/skinning/skinning-plugin.ts +23 -41
  309. package/src/graphics/scene/model/geometry/public.ts +1 -1
  310. package/src/graphics/scene/model/mesh/mesh.ts +18 -0
  311. package/src/graphics/scene/model/mesh/public.ts +3 -0
  312. package/src/graphics/scene/model/mesh-plugin.ts +102 -0
  313. package/src/graphics/scene/model/model-loader-plugin.ts +25 -43
  314. package/src/graphics/scene/model/model-plugin.ts +1 -44
  315. package/src/graphics/scene/model/model.ts +2 -6
  316. package/src/graphics/scene/model/public.ts +3 -1
  317. package/src/graphics/scene/model/shape/bounds-from-shape-mesh.ts +20 -0
  318. package/src/graphics/scene/model/shape/shape-geometry-plugin.ts +97 -18
  319. package/src/graphics/scene/model/shape/shape-spec.ts +9 -0
  320. package/src/graphics/scene/model/world-bounds-plugin.ts +6 -25
  321. package/src/graphics/scene/node/node-data-plugin.test.ts +47 -0
  322. package/src/graphics/scene/node/node-data-plugin.ts +12 -5
  323. package/src/graphics/scene/scene-plugin.ts +3 -3
  324. package/src/index.ts +1 -70
  325. package/src/material/assemble-material-row.ts +26 -0
  326. package/src/material/definitions.ts +427 -0
  327. package/src/material/emission-mode.ts +11 -0
  328. package/src/material/index.ts +3 -0
  329. package/src/material/json/from-json-string.ts +11 -0
  330. package/src/material/json/from-json.test.ts +50 -0
  331. package/src/material/json/from-json.ts +23 -0
  332. package/src/material/json/is-properties-json.ts +77 -0
  333. package/src/material/json/library-json.ts +4 -0
  334. package/src/material/json/load-json.ts +15 -0
  335. package/src/material/json/properties-json.ts +25 -0
  336. package/src/material/json/public.ts +9 -0
  337. package/src/material/json/to-definition.ts +70 -0
  338. package/src/material/material-by-name-lookup.ts +10 -0
  339. package/src/material/material-defaults.ts +26 -0
  340. package/src/material/material-definition.ts +4 -0
  341. package/src/material/material-name.ts +3 -0
  342. package/src/material/material-plugin.test.ts +97 -0
  343. package/src/material/material-plugin.ts +67 -39
  344. package/src/material/material.ts +35 -34
  345. package/src/material/public.ts +12 -2
  346. package/src/material/require-material.ts +15 -0
  347. package/src/material/standard-material-names.ts +4 -0
  348. package/src/material/standard-materials.ts +21 -27
  349. package/src/material/stress-strain-curve/create.ts +9 -0
  350. package/src/material/stress-strain-curve/public.ts +2 -0
  351. package/src/material/stress-strain-curve/schema.test.ts +20 -0
  352. package/src/material/stress-strain-curve/schema.ts +20 -0
  353. package/src/material/stress-strain-curve/stress-strain-curve.ts +11 -0
  354. package/src/physics/README.md +9 -1
  355. package/src/physics/body/collider-shape/mass-from-volume.test.ts +8 -0
  356. package/src/physics/body/collider-shape/mass-from-volume.ts +4 -0
  357. package/src/physics/collider-primitive-render-archetype.ts +5 -0
  358. package/src/physics/collider-primitive-render-archetypes.ts +9 -0
  359. package/src/physics/index.ts +3 -0
  360. package/src/physics/is-voxel-shape-physics-pending.ts +9 -0
  361. package/src/physics/physics-clock/physics-clock.ts +17 -0
  362. package/src/physics/physics-clock-plugin.ts +1 -24
  363. package/src/physics/physics-clock.test.ts +2 -1
  364. package/src/physics/physics-data-plugin.ts +8 -6
  365. package/src/physics/public.ts +23 -0
  366. package/src/physics/ragdoll/bone-capsule.ts +11 -0
  367. package/src/physics/ragdoll/fit-bone-capsules-input.ts +14 -0
  368. package/src/physics/ragdoll/fit-bone-capsules.test.ts +2 -1
  369. package/src/physics/ragdoll/fit-bone-capsules.ts +2 -27
  370. package/src/physics/ragdoll/skin-vertices.ts +8 -0
  371. package/src/physics/rigid-body-components.ts +13 -0
  372. package/src/physics/solvers/README.md +4 -0
  373. package/src/physics/solvers/jolt-solver-plugin.ts +19 -5
  374. package/src/physics/solvers/rapier-solver-plugin.ts +5 -2
  375. package/src/physics/solvers/solver-benchmark-options.ts +16 -0
  376. package/src/physics/solvers/solver-benchmark-result.ts +17 -0
  377. package/src/physics/solvers/solver-benchmark.ts +2 -35
  378. package/src/physics/static-collider-components.ts +10 -0
  379. package/tsconfig.tsbuildinfo +1 -1
  380. package/src/graphics/rendering/material-gpu/material-arrays.ts +0 -113
  381. package/src/graphics/rendering/material-gpu/material-bind-group.ts +0 -61
  382. package/src/graphics/rendering/material-gpu/material-gpu-plugin.ts +0 -95
  383. package/src/graphics/scene/model/geometry/geometry.ts +0 -12
@@ -2,79 +2,37 @@
2
2
 
3
3
  import { Database, type Entity } from "@adobe/data/ecs";
4
4
  import { pbrIblRender } from "../ibl-render/ibl-render-plugin.js";
5
- import { materialGpu } from "../material-gpu/material-gpu-plugin.js";
5
+ import { materialPaletteGpu } from "../material-palette-gpu/material-palette-gpu-plugin.js";
6
6
  import { displayTransform } from "../display-transform-plugin.js";
7
7
  import { SceneUniforms } from "../../scene/scene-uniforms/scene-uniforms.js";
8
8
  import { StandardVertex } from "../standard-vertex/standard-vertex.js";
9
- import { createMaterialBindGroupLayout } from "../material-gpu/material-bind-group.js";
10
- import { buildPbrArrayShader } from "./pbr-array-shader.wgsl.js";
11
-
12
- // Must match pbrIblRender's bake so the array shader's prefiltered-mip math agrees.
13
- const PREFILTERED_MIP_COUNT = 7;
14
-
15
- /** Drawable: any visible entity with a geometry ref, a transform, and a material. */
16
- const DRAWABLE = ["geometry", "visible", "position", "rotation", "scale", "material"] as const;
17
- // Bodies carrying a derived display pose (interpolation-plugin) draw at it instead
18
- // of the canonical pose; everything else (statics, props, non-physics instances)
19
- // draws straight from position/rotation. Splitting the gather by archetype shape
20
- // avoids a per-row "has display pose?" branch.
21
- const DRAWABLE_INTERP = [...DRAWABLE, "_renderPosition", "_renderRotation"] as const;
22
- const DRAWABLE_DIRECT = { exclude: ["_renderPosition"] } as const;
23
- const PRIMITIVE = ["_vertexBuffer", "_indexBuffer", "_indexCount", "_indexFormat", "_geometry", "_nodeLocalMatrix"] as const;
24
-
25
- /** Minimal column shape the gather reads — satisfied by either query's columns. */
26
- interface Col<T> { get(i: number): T }
27
-
28
- function createIblBindGroupLayout(device: GPUDevice): GPUBindGroupLayout {
29
- return device.createBindGroupLayout({
30
- entries: [
31
- { binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "cube" } },
32
- { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "cube" } },
33
- { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: "float", viewDimension: "2d" } },
34
- { binding: 3, visibility: GPUShaderStage.FRAGMENT, sampler: { type: "filtering" } },
35
- ],
36
- });
37
- }
9
+ import { createFactorPaletteBindGroupLayout } from "../material-palette-gpu/palette-bind-group.js";
10
+ import { buildPbrFactorShader } from "./pbr-factor-shader.wgsl.js";
11
+ import {
12
+ composeTrs,
13
+ createIblBindGroupLayout,
14
+ DRAWABLE,
15
+ DRAWABLE_DIRECT,
16
+ DRAWABLE_INTERP,
17
+ PREFILTERED_MIP_COUNT,
18
+ PRIMITIVE,
19
+ type ColumnReader,
20
+ type MeshBatch,
21
+ } from "./primitive-render-shared.js";
22
+
23
+ interface InstCache { buffer: GPUBuffer; indexBuffer: GPUBuffer; bindGroup: GPUBindGroup; capacity: number }
38
24
 
39
25
  /**
40
- * Compose a column-major TRS matrix directly into `out[o..o+15]` — no
41
- * allocation, reading position/rotation/scale straight from their column typed
42
- * arrays. Matches `translation · Quat.toMat4 · scaling`. Runs once per visible
43
- * drawable per frame, so the array churn of the math-helper form matters.
44
- */
45
- function composeTrs(
46
- out: Float32Array, o: number,
47
- p: ArrayLike<number>, pi: number, q: ArrayLike<number>, qi: number, s: ArrayLike<number>, si: number,
48
- ): void {
49
- const qx = q[qi], qy = q[qi + 1], qz = q[qi + 2], qw = q[qi + 3];
50
- const sx = s[si], sy = s[si + 1], sz = s[si + 2];
51
- const xx = qx * qx, yy = qy * qy, zz = qz * qz;
52
- const xy = qx * qy, xz = qx * qz, yz = qy * qz;
53
- const wx = qw * qx, wy = qw * qy, wz = qw * qz;
54
- out[o] = (1 - 2 * (yy + zz)) * sx; out[o + 1] = (2 * (xy + wz)) * sx; out[o + 2] = (2 * (xz - wy)) * sx; out[o + 3] = 0;
55
- out[o + 4] = (2 * (xy - wz)) * sy; out[o + 5] = (1 - 2 * (xx + zz)) * sy; out[o + 6] = (2 * (yz + wx)) * sy; out[o + 7] = 0;
56
- out[o + 8] = (2 * (xz + wy)) * sz; out[o + 9] = (2 * (yz - wx)) * sz; out[o + 10] = (1 - 2 * (xx + yy)) * sz; out[o + 11] = 0;
57
- out[o + 12] = p[pi]; out[o + 13] = p[pi + 1]; out[o + 14] = p[pi + 2]; out[o + 15] = 1;
58
- }
59
-
60
- /**
61
- * pbrRender — the single PBR + IBL renderer. It extends `pbrIblRender`, reusing
62
- * its IBL bake, skybox, scene/material bind groups and glTF draw path verbatim,
63
- * and adds one extra draw query for **instanced primitives** whose material
64
- * comes from the shared `materialGpu` arrays (selected per instance by the
65
- * material entity's `_layerIndex`). Two efficient queries, one render plugin:
66
- *
67
- * - glTF models → per-material bind group, native-resolution textures (pbrIblRender)
68
- * - primitives → shared texture_2d_array + per-instance layer (this system)
26
+ * pbrFactorRender — instanced primitive PBR from material factors only (no map
27
+ * sampling). Extends `pbrIblRender` for IBL + skybox + optional glTF draws.
28
+ * Pairs with `materialPaletteGpu` (`_paletteIndex` on factor materials).
69
29
  *
70
- * The primitive system runs after `pbrIblRenderSystem` so the skybox is drawn
71
- * first. World matrices are computed directly from `position`/`rotation`/`scale`
72
- * (primitives are flat — no hierarchy), so it's independent of `transform`.
30
+ * Pairs with `materialPaletteGpu` (`_paletteIndex`). Idle when no factor materials or drawables exist.
73
31
  */
74
- export const pbrRender = Database.Plugin.create({
75
- extends: Database.Plugin.combine(pbrIblRender, materialGpu, displayTransform),
32
+ export const pbrFactorRender = Database.Plugin.create({
33
+ extends: Database.Plugin.combine(pbrIblRender, materialPaletteGpu, displayTransform),
76
34
  systems: {
77
- pbrPrimitiveRenderSystem: {
35
+ pbrFactorPrimitiveRenderSystem: {
78
36
  schedule: { during: ["render"], after: ["beginRenderPass", "pbrIblRenderSystem"], before: ["endRenderPass"] },
79
37
  create: db => {
80
38
  let pipeline: GPURenderPipeline | null = null;
@@ -87,25 +45,21 @@ export const pbrRender = Database.Plugin.create({
87
45
  let cachedSceneBuffer: GPUBuffer | null = null;
88
46
  let cachedIrradiance: GPUTexture | null = null;
89
47
 
90
- let matLayer = new Map<Entity, number>();
48
+ const matIndex = new Map<Entity, number>();
91
49
  let matCount = -1;
92
50
 
93
- interface Inst { buffer: GPUBuffer; layerBuffer: GPUBuffer; bindGroup: GPUBindGroup; capacity: number }
94
- const instCache = new Map<Entity, Inst>();
51
+ const instCache = new Map<Entity, InstCache>();
95
52
  let matScratch = new Float32Array(16);
96
- let layerScratch = new Uint32Array(1);
97
- // Per-frame matrix arena (composed TRS, one mat4 per drawable) + per-geometry
98
- // draw lists (matrix offset + layer). All pooled and reused across frames —
99
- // the gather runs over every visible body each frame, so zero allocation here.
53
+ let indexScratch = new Uint32Array(1);
100
54
  let mats = new Float32Array(64 * 16);
101
- const batches = new Map<Entity, { off: number[]; layer: number[] }>();
55
+ const batches = new Map<Entity, MeshBatch>();
102
56
 
103
57
  return () => {
104
58
  const {
105
59
  device, renderPassEncoder, canvasFormat, depthFormat, _sceneUniformsBuffer,
106
- _materialBindGroup, _iblIrradiance, _iblPrefiltered, _iblBrdfLut,
60
+ _factorPaletteBindGroup, _iblIrradiance, _iblPrefiltered, _iblBrdfLut,
107
61
  } = db.store.resources;
108
- if (!device || !renderPassEncoder || !_sceneUniformsBuffer || !_materialBindGroup) return;
62
+ if (!device || !renderPassEncoder || !_sceneUniformsBuffer || !_factorPaletteBindGroup) return;
109
63
  if (!_iblIrradiance || !_iblPrefiltered || !_iblBrdfLut) return;
110
64
 
111
65
  if (!sceneLayout) sceneLayout = SceneUniforms.createBindGroupLayout(device);
@@ -121,9 +75,11 @@ export const pbrRender = Database.Plugin.create({
121
75
  addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge", addressModeW: "clamp-to-edge",
122
76
  });
123
77
  if (!pipeline) {
124
- const module = device.createShaderModule({ code: buildPbrArrayShader({ prefilteredMipCount: PREFILTERED_MIP_COUNT }) });
78
+ const module = device.createShaderModule({ code: buildPbrFactorShader({ prefilteredMipCount: PREFILTERED_MIP_COUNT }) });
125
79
  pipeline = device.createRenderPipeline({
126
- layout: device.createPipelineLayout({ bindGroupLayouts: [sceneLayout, createMaterialBindGroupLayout(device), iblLayout, instanceLayout] }),
80
+ layout: device.createPipelineLayout({
81
+ bindGroupLayouts: [sceneLayout, createFactorPaletteBindGroupLayout(device), iblLayout, instanceLayout],
82
+ }),
127
83
  vertex: { module, entryPoint: "vs_main", buffers: [StandardVertex.layout] },
128
84
  fragment: { module, entryPoint: "fs_main", targets: [{ format: canvasFormat }] },
129
85
  primitive: { topology: "triangle-list", cullMode: "back" },
@@ -148,62 +104,58 @@ export const pbrRender = Database.Plugin.create({
148
104
  cachedIrradiance = _iblIrradiance;
149
105
  }
150
106
 
151
- // material → layer, refreshed only when the material set grows
152
107
  let mc = 0;
153
- for (const arch of db.store.queryArchetypes(["_layerIndex"])) mc += arch.rowCount;
108
+ for (const arch of db.store.queryArchetypes(["_paletteIndex"])) mc += arch.rowCount;
154
109
  if (mc !== matCount) {
155
- matLayer = new Map();
156
- for (const arch of db.store.queryArchetypes(["_layerIndex"])) {
157
- const id = arch.columns.id, li = arch.columns._layerIndex;
158
- for (let i = 0; i < arch.rowCount; i++) matLayer.set(id.get(i), li.get(i));
110
+ matIndex.clear();
111
+ for (const arch of db.store.queryArchetypes(["_paletteIndex"])) {
112
+ const id = arch.columns.id, pi = arch.columns._paletteIndex;
113
+ for (let i = 0; i < arch.rowCount; i++) matIndex.set(id.get(i), pi.get(i));
159
114
  }
160
115
  matCount = mc;
161
116
  }
162
117
 
163
- // Gather visible primitive drawables grouped by geometry. Compose each
164
- // world matrix straight from the chosen pose/scale column typed arrays
165
- // into the pooled `mats` arena — no per-row array allocation. Two passes:
166
- // bodies with a display pose use it; everything else uses position/rotation.
167
- for (const b of batches.values()) { b.off.length = 0; b.layer.length = 0; }
118
+ for (const b of batches.values()) { b.off.length = 0; b.materialIndex.length = 0; }
168
119
  let drawCount = 0;
169
120
  const gather = (
170
- rowCount: number, vis: Col<boolean>, geo: Col<Entity>, mat: Col<Entity>,
121
+ rowCount: number, vis: ColumnReader<boolean>, meshCol: ColumnReader<Entity>, mat: ColumnReader<Entity>,
171
122
  posArr: ArrayLike<number>, rotArr: ArrayLike<number>, sclArr: ArrayLike<number>,
172
123
  ): void => {
173
124
  for (let i = 0; i < rowCount; i++) {
174
125
  if (!vis.get(i)) continue;
175
- const layer = matLayer.get(mat.get(i));
176
- if (layer === undefined) continue;
126
+ const paletteIndex = matIndex.get(mat.get(i));
127
+ if (paletteIndex === undefined) continue;
177
128
  if ((drawCount + 1) * 16 > mats.length) { const grown = new Float32Array(mats.length * 2); grown.set(mats); mats = grown; }
178
129
  composeTrs(mats, drawCount * 16, posArr, i * 3, rotArr, i * 4, sclArr, i * 3);
179
- const g = geo.get(i);
130
+ const g = meshCol.get(i);
180
131
  let b = batches.get(g);
181
- if (!b) { b = { off: [], layer: [] }; batches.set(g, b); }
182
- b.off.push(drawCount); b.layer.push(layer);
132
+ if (!b) { b = { off: [], materialIndex: [] }; batches.set(g, b); }
133
+ b.off.push(drawCount);
134
+ b.materialIndex.push(paletteIndex);
183
135
  drawCount++;
184
136
  }
185
137
  };
186
138
  for (const arch of db.store.queryArchetypes(DRAWABLE_INTERP)) {
187
- gather(arch.rowCount, arch.columns.visible, arch.columns.geometry, arch.columns.material,
139
+ gather(arch.rowCount, arch.columns.visible, arch.columns.mesh, arch.columns.material,
188
140
  arch.columns._renderPosition.getTypedArray(), arch.columns._renderRotation.getTypedArray(), arch.columns.scale.getTypedArray());
189
141
  }
190
142
  for (const arch of db.store.queryArchetypes(DRAWABLE, DRAWABLE_DIRECT)) {
191
- gather(arch.rowCount, arch.columns.visible, arch.columns.geometry, arch.columns.material,
143
+ gather(arch.rowCount, arch.columns.visible, arch.columns.mesh, arch.columns.material,
192
144
  arch.columns.position.getTypedArray(), arch.columns.rotation.getTypedArray(), arch.columns.scale.getTypedArray());
193
145
  }
194
146
  if (drawCount === 0) return;
195
147
 
196
148
  renderPassEncoder.setPipeline(pipeline);
197
149
  renderPassEncoder.setBindGroup(0, sceneBindGroup);
198
- renderPassEncoder.setBindGroup(1, _materialBindGroup);
150
+ renderPassEncoder.setBindGroup(1, _factorPaletteBindGroup);
199
151
  renderPassEncoder.setBindGroup(2, iblBindGroup);
200
152
 
201
153
  for (const arch of db.store.queryArchetypes(PRIMITIVE)) {
202
154
  const vbs = arch.columns._vertexBuffer, ibs = arch.columns._indexBuffer;
203
155
  const counts = arch.columns._indexCount, formats = arch.columns._indexFormat;
204
- const geoRefs = arch.columns._geometry, primIds = arch.columns.id;
156
+ const meshRefs = arch.columns._mesh, primIds = arch.columns.id;
205
157
  for (let i = 0; i < arch.rowCount; i++) {
206
- const b = batches.get(geoRefs.get(i));
158
+ const b = batches.get(meshRefs.get(i));
207
159
  if (!b || b.off.length === 0) continue;
208
160
  const n = b.off.length;
209
161
  const primId = primIds.get(i);
@@ -211,32 +163,29 @@ export const pbrRender = Database.Plugin.create({
211
163
  let entry = instCache.get(primId);
212
164
  if (!entry || entry.capacity < n) {
213
165
  entry?.buffer.destroy();
214
- entry?.layerBuffer.destroy();
166
+ entry?.indexBuffer.destroy();
215
167
  const buffer = device.createBuffer({ size: Math.max(n * 64, 64), usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
216
- const layerBuffer = device.createBuffer({ size: Math.max(n * 4, 4), usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
168
+ const indexBuffer = device.createBuffer({ size: Math.max(n * 4, 4), usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
217
169
  const bindGroup = device.createBindGroup({
218
170
  layout: instanceLayout,
219
- entries: [{ binding: 0, resource: { buffer } }, { binding: 1, resource: { buffer: layerBuffer } }],
171
+ entries: [{ binding: 0, resource: { buffer } }, { binding: 1, resource: { buffer: indexBuffer } }],
220
172
  });
221
- entry = { buffer, layerBuffer, bindGroup, capacity: n };
173
+ entry = { buffer, indexBuffer, bindGroup, capacity: n };
222
174
  instCache.set(primId, entry);
223
175
  }
224
176
  if (matScratch.length < n * 16) matScratch = new Float32Array(n * 16);
225
- if (layerScratch.length < n) layerScratch = new Uint32Array(n);
226
- // Copy this geometry's matrices out of the arena into a contiguous
227
- // upload buffer. Primitive node matrices are identity (flat shapes;
228
- // glTF hierarchy goes through pbrIblRender), so no extra multiply.
177
+ if (indexScratch.length < n) indexScratch = new Uint32Array(n);
229
178
  for (let j = 0; j < n; j++) {
230
179
  const src = b.off[j] * 16, dst = j * 16;
231
180
  for (let k = 0; k < 16; k++) matScratch[dst + k] = mats[src + k];
232
- layerScratch[j] = b.layer[j];
181
+ indexScratch[j] = b.materialIndex[j];
233
182
  }
234
183
  device.queue.writeBuffer(entry.buffer, 0, matScratch, 0, n * 16);
235
- device.queue.writeBuffer(entry.layerBuffer, 0, layerScratch, 0, n);
184
+ device.queue.writeBuffer(entry.indexBuffer, 0, indexScratch, 0, n);
236
185
 
237
186
  renderPassEncoder.setBindGroup(3, entry.bindGroup);
238
- renderPassEncoder.setVertexBuffer(0, vbs.get(i)!); // _PbrPrimitive guarantees non-null
239
- renderPassEncoder.setIndexBuffer(ibs.get(i)!, formats.get(i)); // _PbrPrimitive guarantees non-null
187
+ renderPassEncoder.setVertexBuffer(0, vbs.get(i)!);
188
+ renderPassEncoder.setIndexBuffer(ibs.get(i)!, formats.get(i));
240
189
  renderPassEncoder.drawIndexed(counts.get(i), n);
241
190
  }
242
191
  }
@@ -5,13 +5,10 @@ import { schema as sceneUniformsSchema } from "../../scene/scene-uniforms/schema
5
5
  import brdf from "../ibl-render/brdf.wgsl.js";
6
6
 
7
7
  /**
8
- * Unified PBR shader for instanced primitives (and, after convergence, glTF).
9
- * Materials come from the shared `materialGpu` set — five `texture_2d_array`s +
10
- * a palette of per-layer factors (group 1) — selected by a per-instance layer
11
- * index (group 3, binding 1). Shading is identical Cook-Torrance + split-sum
12
- * IBL to the per-material `ibl-shader`; only the material *source* differs.
8
+ * Factor-only PBR for instanced primitives — palette factors + vertex normals,
9
+ * no material map sampling. Used by `pbrFactorRender`.
13
10
  */
14
- export function buildPbrArrayShader(options: { prefilteredMipCount: number }): string {
11
+ export function buildPbrFactorShader(options: { prefilteredMipCount: number }): string {
15
12
  return /* wgsl */ `
16
13
  struct SceneUniforms {
17
14
  ${wgslStructFields(sceneUniformsSchema)}
@@ -20,18 +17,13 @@ ${wgslStructFields(sceneUniformsSchema)}
20
17
  struct MaterialFactors {
21
18
  baseColorFactor: vec4f,
22
19
  emissiveMetallic: vec4f, // emissive.rgb, metallicFactor
23
- roughNormalOcc: vec4f, // roughnessFactor, normalScale, occlusionStrength, _
20
+ roughNormalIr: vec4f, // roughnessFactor, normalScale, occlusionStrength, irEmission
21
+ emissionMeta: vec4f, // emissionMode, _, _, _
24
22
  }
25
23
 
26
24
  @group(0) @binding(0) var<uniform> scene: SceneUniforms;
27
25
 
28
26
  @group(1) @binding(0) var<storage, read> palette: array<MaterialFactors>;
29
- @group(1) @binding(1) var baseColorArray: texture_2d_array<f32>;
30
- @group(1) @binding(2) var metallicRoughnessArray: texture_2d_array<f32>;
31
- @group(1) @binding(3) var normalArray: texture_2d_array<f32>;
32
- @group(1) @binding(4) var occlusionArray: texture_2d_array<f32>;
33
- @group(1) @binding(5) var emissiveArray: texture_2d_array<f32>;
34
- @group(1) @binding(6) var matSampler: sampler;
35
27
 
36
28
  @group(2) @binding(0) var iblIrradiance: texture_cube<f32>;
37
29
  @group(2) @binding(1) var iblPrefiltered: texture_cube<f32>;
@@ -39,7 +31,7 @@ struct MaterialFactors {
39
31
  @group(2) @binding(3) var iblSampler: sampler;
40
32
 
41
33
  @group(3) @binding(0) var<storage, read> instances: array<mat4x4<f32>>;
42
- @group(3) @binding(1) var<storage, read> layers: array<u32>;
34
+ @group(3) @binding(1) var<storage, read> paletteIndices: array<u32>;
43
35
 
44
36
  const PREFILTERED_MIP_COUNT: f32 = ${options.prefilteredMipCount.toFixed(1)};
45
37
 
@@ -54,10 +46,7 @@ struct VertexOutput {
54
46
  @builtin(position) clipPosition: vec4f,
55
47
  @location(0) worldPosition: vec3f,
56
48
  @location(1) normal: vec3f,
57
- @location(2) tangent: vec3f,
58
- @location(3) bitangent: vec3f,
59
- @location(4) uv: vec2f,
60
- @location(5) @interpolate(flat) layer: u32,
49
+ @location(5) @interpolate(flat) paletteIndex: u32,
61
50
  }
62
51
 
63
52
  @vertex
@@ -74,10 +63,7 @@ fn vs_main(@builtin(instance_index) instanceIndex: u32, in: VertexInput) -> Vert
74
63
  out.clipPosition = scene.viewProjectionMatrix * worldPos;
75
64
  out.worldPosition = worldPos.xyz;
76
65
  out.normal = normalize(normalMat * in.normal);
77
- out.tangent = normalize(m3 * in.tangent.xyz);
78
- out.bitangent = normalize(cross(out.normal, out.tangent) * in.tangent.w);
79
- out.uv = in.uv;
80
- out.layer = layers[instanceIndex];
66
+ out.paletteIndex = paletteIndices[instanceIndex];
81
67
  return out;
82
68
  }
83
69
 
@@ -85,32 +71,26 @@ ${brdf}
85
71
 
86
72
  @fragment
87
73
  fn fs_main(in: VertexOutput) -> @location(0) vec4f {
88
- let f = palette[in.layer];
89
- let li = i32(in.layer);
74
+ let f = palette[in.paletteIndex];
90
75
 
91
- let baseColor = textureSample(baseColorArray, matSampler, in.uv, li) * f.baseColorFactor;
92
-
93
- let mr = textureSample(metallicRoughnessArray, matSampler, in.uv, li);
94
- let metallic = mr.b * f.emissiveMetallic.w;
95
- var roughness = mr.g * f.roughNormalOcc.x;
76
+ let baseColor = f.baseColorFactor;
77
+ let metallic = f.emissiveMetallic.w;
78
+ var roughness = f.roughNormalIr.x;
96
79
  roughness = max(roughness, MIN_ROUGHNESS);
97
80
  let alpha = roughness * roughness;
81
+ let occlusion = f.roughNormalIr.z;
82
+ let emissionMode = f.emissionMeta.x;
83
+ let irEmission = f.roughNormalIr.w;
84
+ // 0 = UV fluorescence (no visible add); 1 = visible luminescence (emissive + IR glow).
85
+ let emissive = select(vec3f(0.0), f.emissiveMetallic.xyz + vec3f(irEmission), emissionMode >= 0.5);
98
86
 
99
- let occlusion = textureSample(occlusionArray, matSampler, in.uv, li).r;
100
- let emissive = textureSample(emissiveArray, matSampler, in.uv, li).rgb * f.emissiveMetallic.xyz;
101
-
102
- let nSampled = textureSample(normalArray, matSampler, in.uv, li).rgb * 2.0 - vec3f(1.0);
103
- let nScaled = vec3f(nSampled.xy * f.roughNormalOcc.y, nSampled.z);
104
- let tbn = mat3x3<f32>(in.tangent, in.bitangent, in.normal);
105
- let N = normalize(tbn * nScaled);
106
-
87
+ let N = normalize(in.normal);
107
88
  let V = normalize(scene.cameraPosition - in.worldPosition);
108
89
  let nDotV = max(dot(N, V), 0.001);
109
90
  let R = reflect(-V, N);
110
91
 
111
92
  let f0 = mix(vec3f(0.04), baseColor.rgb, metallic);
112
93
 
113
- // --- IBL contribution (split-sum) ---
114
94
  let F_ibl = f_schlick_roughness(nDotV, f0, roughness);
115
95
  let kD_ibl = (vec3f(1.0) - F_ibl) * (1.0 - metallic);
116
96
 
@@ -122,9 +102,8 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
122
102
  let envBrdf = textureSampleLevel(iblBrdfLut, iblSampler, vec2f(nDotV, roughness), 0.0).rg;
123
103
  let specularIbl = prefiltered * (F_ibl * envBrdf.x + envBrdf.y);
124
104
 
125
- let ambient = (diffuseIbl + specularIbl) * mix(1.0, occlusion, f.roughNormalOcc.z);
105
+ let ambient = (diffuseIbl + specularIbl) * occlusion;
126
106
 
127
- // --- Direct light (parity with the single scene light) ---
128
107
  let L = normalize(-scene.lightDirection);
129
108
  let H = normalize(V + L);
130
109
  let nDotL = max(dot(N, L), 0.0);
@@ -2,101 +2,127 @@
2
2
 
3
3
  import { Database, type Entity } from "@adobe/data/ecs";
4
4
  import { physicsData } from "../../../physics/physics-data-plugin.js";
5
- import { model } from "../../scene/model/model-plugin.js";
5
+ import { RIGID_BODY_COMPONENTS } from "../../../physics/rigid-body-components.js";
6
+ import { STATIC_COLLIDER_COMPONENTS } from "../../../physics/static-collider-components.js";
7
+ import { mesh } from "../../scene/model/mesh-plugin.js";
6
8
  import { shapeGeometry } from "../../scene/model/shape/shape-geometry-plugin.js";
7
9
  import { capsuleMesh, flatShadedMesh } from "../../scene/model/shape/shape-mesh.js";
8
10
  import { convexHullMesh } from "../../scene/model/shape/convex-hull.js";
9
11
  import { uploadShapeMesh } from "../../scene/model/shape/upload-shape-mesh.js";
12
+ import { boundsFromShapeMesh } from "../../scene/model/shape/bounds-from-shape-mesh.js";
10
13
  import type { ColliderMesh } from "../../../physics/body/collider-mesh.js";
11
14
  import { interpolation } from "../interpolation-plugin.js";
12
15
 
16
+ /** Authored column sets for primitive collider rows (RigidBody, ConvexBody,
17
+ * StaticCollider, MeshCollider). Query by these sets — not the named handle —
18
+ * so solver-tagged variants are found after migration. Rows with
19
+ * `voxelShapeName` are skipped at runtime (mechs voxel bodies). */
20
+ const PRIMITIVE_COLLIDER_QUERIES: readonly {
21
+ include: readonly string[];
22
+ exclude?: readonly string[];
23
+ }[] = [
24
+ { include: RIGID_BODY_COMPONENTS, exclude: ["convexPoints"] },
25
+ { include: [...RIGID_BODY_COMPONENTS, "convexPoints"] },
26
+ { include: STATIC_COLLIDER_COMPONENTS, exclude: ["colliderMesh"] },
27
+ { include: [...STATIC_COLLIDER_COMPONENTS, "colliderMesh"] },
28
+ ];
29
+
30
+ const hasVoxelShapeName = (store: { read(id: Entity): Record<string, unknown> | null }, id: Entity): boolean =>
31
+ store.read(id)?.voxelShapeName != null;
32
+
13
33
  /**
14
- * physicsRenderBridge — makes colliders renderable by `pbrRender`. Once the
15
- * shape geometries exist, every body with a collider shape (dynamic RigidBody
16
- * or immovable StaticCollider alike) gains a `geometry` ref (sphere / cube by
17
- * collider shape), a `scale` (its half-extents — the unit shapes are size-1),
18
- * and `visible`. Because physics `rotation`/`position` are the same components
19
- * the renderer reads, there is no per-frame sync: this only migrates new bodies.
20
- *
21
- * It also folds in `interpolation`, so dynamic bodies render at the smooth,
22
- * render-rate display pose for free (the solver steps on a fixed clock that need
23
- * not match the render rate) — bridging physics to the renderer is exactly when
24
- * you want that. Use `interpolation` directly only with a custom (non-bridge) path.
25
- *
26
- * Also declares `Prop` — a render-only placed geometry with a material that is
27
- * not a physics body at all (decorative scenery with no collider).
34
+ * physicsRenderBridge — assigns default primitive render meshes for standard
35
+ * physics bodies whose visual is the collider primitive (RigidBody,
36
+ * StaticCollider, ConvexBody, MeshCollider — including solver-tagged variants).
37
+ * Collider shape
38
+ * drives the mesh; bodies on other archetypes (e.g. `VoxelRigidBody`) are not
39
+ * touched — their visual path owns `mesh` assignment separately.
28
40
  */
29
41
  export const physicsRenderBridge = Database.Plugin.create({
30
- extends: Database.Plugin.combine(physicsData, model, shapeGeometry, interpolation),
31
- archetypes: {
32
- Prop: ["geometry", "position", "rotation", "scale", "visible", "material"],
33
- },
42
+ imports: Database.Plugin.combine(mesh, shapeGeometry, interpolation),
43
+ extends: physicsData,
34
44
  systems: {
35
45
  physicsBridge: {
46
+ // Runs late in postUpdate so voxel-owned bodies can resolve first;
47
+ // name sorts after `voxelShapeVisualBridge` when both were postUpdate.
36
48
  schedule: { during: ["postUpdate"] },
37
49
  create: db => {
38
- // Sphere/cube are unit meshes scaled by half-extents. A capsule can't
39
- // be non-uniformly scaled (its caps would distort), so it's built at its
40
- // real size and drawn at unit scale — one mesh per distinct (radius,
41
- // half-height), cached here (scenes use very few capsule sizes).
42
- const capsuleGeometry = new Map<string, Entity>();
50
+ const capsuleMeshes = new Map<string, Entity>();
43
51
  const ensureCapsule = (device: GPUDevice, r: number, hy: number): Entity => {
44
52
  const key = `${r}:${hy}`;
45
- let geo = capsuleGeometry.get(key);
46
- if (geo === undefined) {
47
- const m = uploadShapeMesh(device, capsuleMesh(r, hy));
48
- geo = db.transactions.insertShapePrimitive({ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count });
49
- capsuleGeometry.set(key, geo);
53
+ let id = capsuleMeshes.get(key);
54
+ if (id === undefined) {
55
+ const data = capsuleMesh(r, hy);
56
+ const m = uploadShapeMesh(device, data);
57
+ id = db.transactions.insertStaticMeshPrimitive({
58
+ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count,
59
+ localBounds: boundsFromShapeMesh(data),
60
+ });
61
+ capsuleMeshes.set(key, id);
50
62
  }
51
- return geo;
63
+ return id;
52
64
  };
53
- // Hull render mesh = triangulated convex hull of the point cloud, cached
54
- // by the point-array reference (bodies sharing a cloud share one mesh + draw).
55
- const hullGeometry = new Map<Float32Array, Entity>();
65
+ const hullMeshes = new Map<Float32Array, Entity>();
56
66
  const ensureHull = (device: GPUDevice, points: Float32Array): Entity => {
57
- let geo = hullGeometry.get(points);
58
- if (geo === undefined) {
59
- const m = uploadShapeMesh(device, convexHullMesh(points));
60
- geo = db.transactions.insertShapePrimitive({ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count });
61
- hullGeometry.set(points, geo);
67
+ let id = hullMeshes.get(points);
68
+ if (id === undefined) {
69
+ const data = convexHullMesh(points);
70
+ const m = uploadShapeMesh(device, data);
71
+ id = db.transactions.insertStaticMeshPrimitive({
72
+ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count,
73
+ localBounds: boundsFromShapeMesh(data),
74
+ });
75
+ hullMeshes.set(points, id);
62
76
  }
63
- return geo;
77
+ return id;
64
78
  };
65
- // Static-mesh render = flat-shaded triangle soup, cached by the colliderMesh ref.
66
- const meshGeometry = new Map<ColliderMesh, Entity>();
67
- const ensureMesh = (device: GPUDevice, cm: ColliderMesh): Entity => {
68
- let geo = meshGeometry.get(cm);
69
- if (geo === undefined) {
70
- const m = uploadShapeMesh(device, flatShadedMesh(cm.positions, cm.indices));
71
- geo = db.transactions.insertShapePrimitive({ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count });
72
- meshGeometry.set(cm, geo);
79
+ const triMeshes = new Map<ColliderMesh, Entity>();
80
+ const ensureTriMesh = (device: GPUDevice, cm: ColliderMesh): Entity => {
81
+ let id = triMeshes.get(cm);
82
+ if (id === undefined) {
83
+ const data = flatShadedMesh(cm.positions, cm.indices);
84
+ const m = uploadShapeMesh(device, data);
85
+ id = db.transactions.insertStaticMeshPrimitive({
86
+ vertexBuffer: m.vb, indexBuffer: m.ib, indexCount: m.count,
87
+ localBounds: boundsFromShapeMesh(data),
88
+ });
89
+ triMeshes.set(cm, id);
73
90
  }
74
- return geo;
91
+ return id;
75
92
  };
76
93
  return () => {
77
- const shapes = db.store.resources._shapeGeometry;
94
+ const shapes = db.store.resources._shapeMeshes;
78
95
  const device = db.store.resources.device;
79
96
  if (!shapes || !device) return;
80
- for (const arch of db.store.queryArchetypes(["colliderShape", "halfExtents"], { exclude: ["geometry"] })) {
81
- const ids = arch.columns.id, css = arch.columns.colliderShape, hes = arch.columns.halfExtents;
82
- // Tail→head: every visited body migrates out (gains geometry).
83
- for (let i = arch.rowCount - 1; i >= 0; i--) {
84
- const id = ids.get(i), shape = css.get(i), he = hes.get(i);
85
- // capsule + hull render at unit scale (their meshes are real-size);
86
- // sphere/cube are unit meshes scaled by half-extents.
87
- let geometry: Entity, scale: [number, number, number];
88
- if (shape === "box") { geometry = shapes.cube; scale = [he[0], he[1], he[2]]; }
89
- else if (shape === "capsule") { geometry = ensureCapsule(device, he[0], he[1]); scale = [1, 1, 1]; }
90
- else if (shape === "hull") {
91
- const pts = (db.store.read(id) as { convexPoints?: Float32Array | null }).convexPoints;
92
- geometry = pts ? ensureHull(device, pts) : shapes.sphere;
93
- scale = [1, 1, 1];
94
- } else if (shape === "mesh") {
95
- const cm = (db.store.read(id) as { colliderMesh?: ColliderMesh | null }).colliderMesh;
96
- geometry = cm ? ensureMesh(device, cm) : shapes.cube;
97
- scale = [1, 1, 1];
98
- } else { geometry = shapes.sphere; scale = [he[0], he[0], he[0]]; }
99
- db.store.update(id, { geometry, scale, visible: true });
97
+ for (const { include, exclude } of PRIMITIVE_COLLIDER_QUERIES) {
98
+ for (const arch of db.store.queryArchetypes(
99
+ include as typeof RIGID_BODY_COMPONENTS,
100
+ exclude ? { exclude: exclude as ["convexPoints"] | ["colliderMesh"] } : undefined,
101
+ )) {
102
+ const ids = arch.columns.id;
103
+ const css = arch.columns.colliderShape;
104
+ const hes = arch.columns.halfExtents;
105
+ for (let i = arch.rowCount - 1; i >= 0; i--) {
106
+ const id = ids.get(i);
107
+ if (hasVoxelShapeName(db.store, id)) continue;
108
+ if (db.store.get(id, "mesh") != null) continue;
109
+ const shape = css.get(i);
110
+ const he = hes.get(i);
111
+ let meshId: Entity;
112
+ let scale: [number, number, number];
113
+ if (shape === "box") { meshId = shapes.cube; scale = [he[0], he[1], he[2]]; }
114
+ else if (shape === "capsule") { meshId = ensureCapsule(device, he[0], he[1]); scale = [1, 1, 1]; }
115
+ else if (shape === "hull") {
116
+ const pts = db.store.get(id, "convexPoints");
117
+ meshId = pts ? ensureHull(device, pts) : shapes.sphere;
118
+ scale = [1, 1, 1];
119
+ } else if (shape === "mesh") {
120
+ const cm = db.store.get(id, "colliderMesh");
121
+ meshId = cm ? ensureTriMesh(device, cm) : shapes.cube;
122
+ scale = [1, 1, 1];
123
+ } else { meshId = shapes.sphere; scale = [he[0], he[0], he[0]]; }
124
+ db.store.update(id, { mesh: meshId, scale, visible: true });
125
+ }
100
126
  }
101
127
  }
102
128
  };