@ifc-lite/renderer 3.2.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. package/dist/aabb-edges.d.ts +10 -0
  2. package/dist/aabb-edges.d.ts.map +1 -1
  3. package/dist/aabb-edges.js +13 -0
  4. package/dist/aabb-edges.js.map +1 -1
  5. package/dist/ao-params.d.ts +85 -0
  6. package/dist/ao-params.d.ts.map +1 -0
  7. package/dist/ao-params.js +109 -0
  8. package/dist/ao-params.js.map +1 -0
  9. package/dist/ao-pass.d.ts +47 -0
  10. package/dist/ao-pass.d.ts.map +1 -0
  11. package/dist/ao-pass.js +157 -0
  12. package/dist/ao-pass.js.map +1 -0
  13. package/dist/camera-matrices.d.ts +3 -0
  14. package/dist/camera-matrices.d.ts.map +1 -1
  15. package/dist/camera-matrices.js +12 -1
  16. package/dist/camera-matrices.js.map +1 -1
  17. package/dist/camera-orientation.d.ts +62 -0
  18. package/dist/camera-orientation.d.ts.map +1 -0
  19. package/dist/camera-orientation.js +155 -0
  20. package/dist/camera-orientation.js.map +1 -0
  21. package/dist/camera-projection.d.ts +3 -1
  22. package/dist/camera-projection.d.ts.map +1 -1
  23. package/dist/camera-projection.js +26 -20
  24. package/dist/camera-projection.js.map +1 -1
  25. package/dist/camera-surface-zoom.d.ts +32 -0
  26. package/dist/camera-surface-zoom.d.ts.map +1 -0
  27. package/dist/camera-surface-zoom.js +37 -0
  28. package/dist/camera-surface-zoom.js.map +1 -0
  29. package/dist/camera.d.ts +32 -61
  30. package/dist/camera.d.ts.map +1 -1
  31. package/dist/camera.js +71 -167
  32. package/dist/camera.js.map +1 -1
  33. package/dist/clash-solid-pipeline.d.ts +9 -3
  34. package/dist/clash-solid-pipeline.d.ts.map +1 -1
  35. package/dist/clash-solid-pipeline.js +31 -8
  36. package/dist/clash-solid-pipeline.js.map +1 -1
  37. package/dist/constants.d.ts +1 -1
  38. package/dist/constants.d.ts.map +1 -1
  39. package/dist/constants.js +4 -3
  40. package/dist/constants.js.map +1 -1
  41. package/dist/depth-reconstruct.d.ts +43 -0
  42. package/dist/depth-reconstruct.d.ts.map +1 -0
  43. package/dist/depth-reconstruct.js +35 -0
  44. package/dist/depth-reconstruct.js.map +1 -0
  45. package/dist/device.js +1 -1
  46. package/dist/device.js.map +1 -1
  47. package/dist/edge-params.d.ts +43 -0
  48. package/dist/edge-params.d.ts.map +1 -0
  49. package/dist/edge-params.js +63 -0
  50. package/dist/edge-params.js.map +1 -0
  51. package/dist/edge-pass.d.ts +38 -0
  52. package/dist/edge-pass.d.ts.map +1 -0
  53. package/dist/edge-pass.js +111 -0
  54. package/dist/edge-pass.js.map +1 -0
  55. package/dist/environment.d.ts +26 -15
  56. package/dist/environment.d.ts.map +1 -1
  57. package/dist/environment.js +24 -13
  58. package/dist/environment.js.map +1 -1
  59. package/dist/federation-registry.d.ts +16 -0
  60. package/dist/federation-registry.d.ts.map +1 -1
  61. package/dist/federation-registry.js +80 -9
  62. package/dist/federation-registry.js.map +1 -1
  63. package/dist/gpu-static-upload.d.ts +39 -0
  64. package/dist/gpu-static-upload.d.ts.map +1 -0
  65. package/dist/gpu-static-upload.js +70 -0
  66. package/dist/gpu-static-upload.js.map +1 -0
  67. package/dist/gpu-upload-guard.d.ts +12 -23
  68. package/dist/gpu-upload-guard.d.ts.map +1 -1
  69. package/dist/gpu-upload-guard.js +12 -26
  70. package/dist/gpu-upload-guard.js.map +1 -1
  71. package/dist/index.d.ts +58 -35
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +255 -284
  74. package/dist/index.js.map +1 -1
  75. package/dist/instanced-render.d.ts +25 -5
  76. package/dist/instanced-render.d.ts.map +1 -1
  77. package/dist/instanced-render.js +50 -13
  78. package/dist/instanced-render.js.map +1 -1
  79. package/dist/instanced-rte.d.ts +17 -0
  80. package/dist/instanced-rte.d.ts.map +1 -0
  81. package/dist/instanced-rte.js +32 -0
  82. package/dist/instanced-rte.js.map +1 -0
  83. package/dist/mesh-material.d.ts +26 -0
  84. package/dist/mesh-material.d.ts.map +1 -0
  85. package/dist/mesh-material.js +52 -0
  86. package/dist/mesh-material.js.map +1 -0
  87. package/dist/mesh-rte-uniforms.d.ts +47 -0
  88. package/dist/mesh-rte-uniforms.d.ts.map +1 -0
  89. package/dist/mesh-rte-uniforms.js +60 -0
  90. package/dist/mesh-rte-uniforms.js.map +1 -0
  91. package/dist/model-bounds-tracker.d.ts +7 -0
  92. package/dist/model-bounds-tracker.d.ts.map +1 -1
  93. package/dist/model-bounds-tracker.js +16 -5
  94. package/dist/model-bounds-tracker.js.map +1 -1
  95. package/dist/model-translation.d.ts +1 -1
  96. package/dist/model-translation.d.ts.map +1 -1
  97. package/dist/model-translation.js +50 -2
  98. package/dist/model-translation.js.map +1 -1
  99. package/dist/overlay-theme-uniforms.d.ts +54 -0
  100. package/dist/overlay-theme-uniforms.d.ts.map +1 -0
  101. package/dist/overlay-theme-uniforms.js +89 -0
  102. package/dist/overlay-theme-uniforms.js.map +1 -0
  103. package/dist/overlay-theme.d.ts +73 -0
  104. package/dist/overlay-theme.d.ts.map +1 -0
  105. package/dist/overlay-theme.js +24 -0
  106. package/dist/overlay-theme.js.map +1 -0
  107. package/dist/pick-rte-snapshot.d.ts +7 -0
  108. package/dist/pick-rte-snapshot.d.ts.map +1 -0
  109. package/dist/pick-rte-snapshot.js +15 -0
  110. package/dist/pick-rte-snapshot.js.map +1 -0
  111. package/dist/pick-types.d.ts +17 -0
  112. package/dist/pick-types.d.ts.map +1 -0
  113. package/dist/pick-types.js +5 -0
  114. package/dist/pick-types.js.map +1 -0
  115. package/dist/pick-uniforms.d.ts +6 -0
  116. package/dist/pick-uniforms.d.ts.map +1 -1
  117. package/dist/pick-uniforms.js +22 -18
  118. package/dist/pick-uniforms.js.map +1 -1
  119. package/dist/pick-world-position.d.ts +18 -0
  120. package/dist/pick-world-position.d.ts.map +1 -0
  121. package/dist/pick-world-position.js +21 -0
  122. package/dist/pick-world-position.js.map +1 -0
  123. package/dist/picker-readbacks.d.ts +6 -0
  124. package/dist/picker-readbacks.d.ts.map +1 -0
  125. package/dist/picker-readbacks.js +20 -0
  126. package/dist/picker-readbacks.js.map +1 -0
  127. package/dist/picker-rte-uniforms.d.ts +6 -0
  128. package/dist/picker-rte-uniforms.d.ts.map +1 -0
  129. package/dist/picker-rte-uniforms.js +41 -0
  130. package/dist/picker-rte-uniforms.js.map +1 -0
  131. package/dist/picker.d.ts +6 -7
  132. package/dist/picker.d.ts.map +1 -1
  133. package/dist/picker.js +88 -115
  134. package/dist/picker.js.map +1 -1
  135. package/dist/picking-manager.d.ts +8 -0
  136. package/dist/picking-manager.d.ts.map +1 -1
  137. package/dist/picking-manager.js +46 -19
  138. package/dist/picking-manager.js.map +1 -1
  139. package/dist/pipeline.d.ts +3 -7
  140. package/dist/pipeline.d.ts.map +1 -1
  141. package/dist/pipeline.js +27 -31
  142. package/dist/pipeline.js.map +1 -1
  143. package/dist/point-picker.d.ts +5 -1
  144. package/dist/point-picker.d.ts.map +1 -1
  145. package/dist/point-picker.js +49 -9
  146. package/dist/point-picker.js.map +1 -1
  147. package/dist/pointcloud/point-cloud-handle-ids.d.ts +22 -0
  148. package/dist/pointcloud/point-cloud-handle-ids.d.ts.map +1 -0
  149. package/dist/pointcloud/point-cloud-handle-ids.js +31 -0
  150. package/dist/pointcloud/point-cloud-handle-ids.js.map +1 -0
  151. package/dist/pointcloud/point-cloud-node.d.ts +14 -6
  152. package/dist/pointcloud/point-cloud-node.d.ts.map +1 -1
  153. package/dist/pointcloud/point-cloud-node.js.map +1 -1
  154. package/dist/pointcloud/point-cloud-pick-sources.d.ts +47 -0
  155. package/dist/pointcloud/point-cloud-pick-sources.d.ts.map +1 -0
  156. package/dist/pointcloud/point-cloud-pick-sources.js +32 -0
  157. package/dist/pointcloud/point-cloud-pick-sources.js.map +1 -0
  158. package/dist/pointcloud/point-cloud-placement.d.ts.map +1 -1
  159. package/dist/pointcloud/point-cloud-placement.js +20 -5
  160. package/dist/pointcloud/point-cloud-placement.js.map +1 -1
  161. package/dist/pointcloud/point-cloud-ray-transform.d.ts +78 -4
  162. package/dist/pointcloud/point-cloud-ray-transform.d.ts.map +1 -1
  163. package/dist/pointcloud/point-cloud-ray-transform.js +31 -84
  164. package/dist/pointcloud/point-cloud-ray-transform.js.map +1 -1
  165. package/dist/pointcloud/point-cloud-renderer.d.ts +21 -19
  166. package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
  167. package/dist/pointcloud/point-cloud-renderer.js +46 -52
  168. package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
  169. package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts +44 -0
  170. package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts.map +1 -0
  171. package/dist/pointcloud/point-cloud-stream-lifecycle.js +44 -0
  172. package/dist/pointcloud/point-cloud-stream-lifecycle.js.map +1 -0
  173. package/dist/pointcloud/point-cloud-uniforms.d.ts +5 -0
  174. package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
  175. package/dist/pointcloud/point-cloud-uniforms.js +55 -44
  176. package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
  177. package/dist/pointcloud/point-cloud-visibility.d.ts +10 -0
  178. package/dist/pointcloud/point-cloud-visibility.d.ts.map +1 -0
  179. package/dist/pointcloud/point-cloud-visibility.js +18 -0
  180. package/dist/pointcloud/point-cloud-visibility.js.map +1 -0
  181. package/dist/pointcloud/point-pipeline.d.ts +4 -9
  182. package/dist/pointcloud/point-pipeline.d.ts.map +1 -1
  183. package/dist/pointcloud/point-pipeline.js +4 -9
  184. package/dist/pointcloud/point-pipeline.js.map +1 -1
  185. package/dist/pointcloud/point-shader.wgsl.d.ts +1 -21
  186. package/dist/pointcloud/point-shader.wgsl.d.ts.map +1 -1
  187. package/dist/pointcloud/point-shader.wgsl.js +25 -5
  188. package/dist/pointcloud/point-shader.wgsl.js.map +1 -1
  189. package/dist/post-pass-chain.d.ts +38 -0
  190. package/dist/post-pass-chain.d.ts.map +1 -0
  191. package/dist/post-pass-chain.js +105 -0
  192. package/dist/post-pass-chain.js.map +1 -0
  193. package/dist/raycast-engine.d.ts +7 -5
  194. package/dist/raycast-engine.d.ts.map +1 -1
  195. package/dist/raycast-engine.js +17 -20
  196. package/dist/raycast-engine.js.map +1 -1
  197. package/dist/raycast-point-cloud-query.d.ts +1 -1
  198. package/dist/raycast-point-cloud-query.d.ts.map +1 -1
  199. package/dist/reference-image-pipeline.d.ts +1 -1
  200. package/dist/reference-image-pipeline.d.ts.map +1 -1
  201. package/dist/reference-image-pipeline.js +25 -7
  202. package/dist/reference-image-pipeline.js.map +1 -1
  203. package/dist/reference-images.d.ts +1 -1
  204. package/dist/reference-images.d.ts.map +1 -1
  205. package/dist/reference-images.js +13 -5
  206. package/dist/reference-images.js.map +1 -1
  207. package/dist/relative-to-eye.d.ts +146 -0
  208. package/dist/relative-to-eye.d.ts.map +1 -0
  209. package/dist/relative-to-eye.js +326 -0
  210. package/dist/relative-to-eye.js.map +1 -0
  211. package/dist/render-section-draw.d.ts +11 -0
  212. package/dist/render-section-draw.d.ts.map +1 -1
  213. package/dist/render-section-draw.js +6 -3
  214. package/dist/render-section-draw.js.map +1 -1
  215. package/dist/renderer-color-readback.d.ts +50 -0
  216. package/dist/renderer-color-readback.d.ts.map +1 -0
  217. package/dist/renderer-color-readback.js +145 -0
  218. package/dist/renderer-color-readback.js.map +1 -0
  219. package/dist/renderer-overlays.d.ts +20 -10
  220. package/dist/renderer-overlays.d.ts.map +1 -1
  221. package/dist/renderer-overlays.js +44 -34
  222. package/dist/renderer-overlays.js.map +1 -1
  223. package/dist/renderer-screenshot.d.ts +4 -0
  224. package/dist/renderer-screenshot.d.ts.map +1 -0
  225. package/dist/renderer-screenshot.js +17 -0
  226. package/dist/renderer-screenshot.js.map +1 -0
  227. package/dist/renderer-symbolic-overlays.d.ts +4 -2
  228. package/dist/renderer-symbolic-overlays.d.ts.map +1 -1
  229. package/dist/renderer-symbolic-overlays.js +33 -13
  230. package/dist/renderer-symbolic-overlays.js.map +1 -1
  231. package/dist/renderer-viewport.d.ts +45 -0
  232. package/dist/renderer-viewport.d.ts.map +1 -1
  233. package/dist/renderer-viewport.js +44 -0
  234. package/dist/renderer-viewport.js.map +1 -1
  235. package/dist/rte-clip-space.d.ts +12 -0
  236. package/dist/rte-clip-space.d.ts.map +1 -0
  237. package/dist/rte-clip-space.js +22 -0
  238. package/dist/rte-clip-space.js.map +1 -0
  239. package/dist/rte-frustum.d.ts +24 -0
  240. package/dist/rte-frustum.d.ts.map +1 -0
  241. package/dist/rte-frustum.js +45 -0
  242. package/dist/rte-frustum.js.map +1 -0
  243. package/dist/scene-batch-upload.d.ts.map +1 -1
  244. package/dist/scene-batch-upload.js +14 -38
  245. package/dist/scene-batch-upload.js.map +1 -1
  246. package/dist/scene-device-recovery.d.ts.map +1 -1
  247. package/dist/scene-device-recovery.js +5 -9
  248. package/dist/scene-device-recovery.js.map +1 -1
  249. package/dist/scene-finalize-regroup.d.ts +54 -0
  250. package/dist/scene-finalize-regroup.d.ts.map +1 -0
  251. package/dist/scene-finalize-regroup.js +136 -0
  252. package/dist/scene-finalize-regroup.js.map +1 -0
  253. package/dist/scene-instance-bounds.d.ts +12 -0
  254. package/dist/scene-instance-bounds.d.ts.map +1 -0
  255. package/dist/scene-instance-bounds.js +48 -0
  256. package/dist/scene-instance-bounds.js.map +1 -0
  257. package/dist/scene-instance-materialization.d.ts +4 -1
  258. package/dist/scene-instance-materialization.d.ts.map +1 -1
  259. package/dist/scene-instance-materialization.js +21 -6
  260. package/dist/scene-instance-materialization.js.map +1 -1
  261. package/dist/scene-instance-translation.d.ts +17 -0
  262. package/dist/scene-instance-translation.d.ts.map +1 -0
  263. package/dist/scene-instance-translation.js +50 -0
  264. package/dist/scene-instance-translation.js.map +1 -0
  265. package/dist/scene-instance-types.d.ts +6 -0
  266. package/dist/scene-instance-types.d.ts.map +1 -1
  267. package/dist/scene-model-translation.d.ts +2 -0
  268. package/dist/scene-model-translation.d.ts.map +1 -1
  269. package/dist/scene-model-translation.js +1 -1
  270. package/dist/scene-model-translation.js.map +1 -1
  271. package/dist/scene-rect-select.d.ts +11 -1
  272. package/dist/scene-rect-select.d.ts.map +1 -1
  273. package/dist/scene-rect-select.js +7 -4
  274. package/dist/scene-rect-select.js.map +1 -1
  275. package/dist/scene.d.ts +27 -20
  276. package/dist/scene.d.ts.map +1 -1
  277. package/dist/scene.js +109 -238
  278. package/dist/scene.js.map +1 -1
  279. package/dist/section-2d-lift.d.ts +10 -2
  280. package/dist/section-2d-lift.d.ts.map +1 -1
  281. package/dist/section-2d-lift.js +14 -6
  282. package/dist/section-2d-lift.js.map +1 -1
  283. package/dist/section-2d-line-buffer.d.ts +12 -4
  284. package/dist/section-2d-line-buffer.d.ts.map +1 -1
  285. package/dist/section-2d-line-buffer.js +59 -33
  286. package/dist/section-2d-line-buffer.js.map +1 -1
  287. package/dist/section-2d-overlay.d.ts +18 -72
  288. package/dist/section-2d-overlay.d.ts.map +1 -1
  289. package/dist/section-2d-overlay.js +72 -103
  290. package/dist/section-2d-overlay.js.map +1 -1
  291. package/dist/section-2d-types.d.ts +38 -0
  292. package/dist/section-2d-types.d.ts.map +1 -0
  293. package/dist/section-2d-types.js +6 -0
  294. package/dist/section-2d-types.js.map +1 -0
  295. package/dist/section-cap-pipelines.d.ts +6 -0
  296. package/dist/section-cap-pipelines.d.ts.map +1 -0
  297. package/dist/section-cap-pipelines.js +87 -0
  298. package/dist/section-cap-pipelines.js.map +1 -0
  299. package/dist/section-plane-geometry.d.ts +24 -0
  300. package/dist/section-plane-geometry.d.ts.map +1 -0
  301. package/dist/section-plane-geometry.js +93 -0
  302. package/dist/section-plane-geometry.js.map +1 -0
  303. package/dist/section-plane.d.ts +26 -24
  304. package/dist/section-plane.d.ts.map +1 -1
  305. package/dist/section-plane.js +57 -182
  306. package/dist/section-plane.js.map +1 -1
  307. package/dist/shaders/ao.wgsl.d.ts +2 -0
  308. package/dist/shaders/ao.wgsl.d.ts.map +1 -0
  309. package/dist/shaders/ao.wgsl.js +234 -0
  310. package/dist/shaders/ao.wgsl.js.map +1 -0
  311. package/dist/shaders/color-transfer.wgsl.d.ts +28 -0
  312. package/dist/shaders/color-transfer.wgsl.d.ts.map +1 -0
  313. package/dist/shaders/color-transfer.wgsl.js +55 -0
  314. package/dist/shaders/color-transfer.wgsl.js.map +1 -0
  315. package/dist/shaders/depth-reconstruct.wgsl.d.ts +16 -0
  316. package/dist/shaders/depth-reconstruct.wgsl.d.ts.map +1 -0
  317. package/dist/shaders/depth-reconstruct.wgsl.js +69 -0
  318. package/dist/shaders/depth-reconstruct.wgsl.js.map +1 -0
  319. package/dist/shaders/edges.wgsl.d.ts +2 -0
  320. package/dist/shaders/edges.wgsl.d.ts.map +1 -0
  321. package/dist/shaders/edges.wgsl.js +158 -0
  322. package/dist/shaders/edges.wgsl.js.map +1 -0
  323. package/dist/shaders/main-rte-shadow.wgsl.d.ts +4 -0
  324. package/dist/shaders/main-rte-shadow.wgsl.d.ts.map +1 -0
  325. package/dist/shaders/main-rte-shadow.wgsl.js +54 -0
  326. package/dist/shaders/main-rte-shadow.wgsl.js.map +1 -0
  327. package/dist/shaders/main.wgsl.d.ts +1 -6
  328. package/dist/shaders/main.wgsl.d.ts.map +1 -1
  329. package/dist/shaders/main.wgsl.js +183 -228
  330. package/dist/shaders/main.wgsl.js.map +1 -1
  331. package/dist/shaders/relative-to-eye.wgsl.d.ts +12 -0
  332. package/dist/shaders/relative-to-eye.wgsl.d.ts.map +1 -0
  333. package/dist/shaders/relative-to-eye.wgsl.js +40 -0
  334. package/dist/shaders/relative-to-eye.wgsl.js.map +1 -0
  335. package/dist/shaders/section-2d-overlay.wgsl.d.ts +28 -12
  336. package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
  337. package/dist/shaders/section-2d-overlay.wgsl.js +40 -13
  338. package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
  339. package/dist/shaders/shadow.wgsl.d.ts +1 -1
  340. package/dist/shaders/shadow.wgsl.d.ts.map +1 -1
  341. package/dist/shaders/shadow.wgsl.js +25 -7
  342. package/dist/shaders/shadow.wgsl.js.map +1 -1
  343. package/dist/shaders/sky.wgsl.d.ts +1 -11
  344. package/dist/shaders/sky.wgsl.d.ts.map +1 -1
  345. package/dist/shaders/sky.wgsl.js +17 -19
  346. package/dist/shaders/sky.wgsl.js.map +1 -1
  347. package/dist/shaders/specular.wgsl.d.ts +34 -0
  348. package/dist/shaders/specular.wgsl.d.ts.map +1 -0
  349. package/dist/shaders/specular.wgsl.js +134 -0
  350. package/dist/shaders/specular.wgsl.js.map +1 -0
  351. package/dist/shaders/symbolic-overlay.wgsl.d.ts +2 -9
  352. package/dist/shaders/symbolic-overlay.wgsl.d.ts.map +1 -1
  353. package/dist/shaders/symbolic-overlay.wgsl.js +88 -17
  354. package/dist/shaders/symbolic-overlay.wgsl.js.map +1 -1
  355. package/dist/shaders/textured.wgsl.d.ts.map +1 -1
  356. package/dist/shaders/textured.wgsl.js +11 -9
  357. package/dist/shaders/textured.wgsl.js.map +1 -1
  358. package/dist/shadow-light-matrix.d.ts +7 -0
  359. package/dist/shadow-light-matrix.d.ts.map +1 -1
  360. package/dist/shadow-light-matrix.js +11 -0
  361. package/dist/shadow-light-matrix.js.map +1 -1
  362. package/dist/shadow-occluder-batches.d.ts +10 -0
  363. package/dist/shadow-occluder-batches.d.ts.map +1 -0
  364. package/dist/shadow-occluder-batches.js +39 -0
  365. package/dist/shadow-occluder-batches.js.map +1 -0
  366. package/dist/shadow-occluders.d.ts.map +1 -1
  367. package/dist/shadow-occluders.js +4 -0
  368. package/dist/shadow-occluders.js.map +1 -1
  369. package/dist/shadow-pass.d.ts +5 -51
  370. package/dist/shadow-pass.d.ts.map +1 -1
  371. package/dist/shadow-pass.js +49 -45
  372. package/dist/shadow-pass.js.map +1 -1
  373. package/dist/shadow-types.d.ts +39 -0
  374. package/dist/shadow-types.d.ts.map +1 -0
  375. package/dist/shadow-types.js +15 -0
  376. package/dist/shadow-types.js.map +1 -0
  377. package/dist/symbolic-overlay-geometry.d.ts +7 -0
  378. package/dist/symbolic-overlay-geometry.d.ts.map +1 -0
  379. package/dist/symbolic-overlay-geometry.js +43 -0
  380. package/dist/symbolic-overlay-geometry.js.map +1 -0
  381. package/dist/symbolic-overlay-pipelines.d.ts +24 -36
  382. package/dist/symbolic-overlay-pipelines.d.ts.map +1 -1
  383. package/dist/symbolic-overlay-pipelines.js +175 -182
  384. package/dist/symbolic-overlay-pipelines.js.map +1 -1
  385. package/dist/symbolic-text-atlas.d.ts +21 -0
  386. package/dist/symbolic-text-atlas.d.ts.map +1 -1
  387. package/dist/symbolic-text-atlas.js +29 -1
  388. package/dist/symbolic-text-atlas.js.map +1 -1
  389. package/dist/types.d.ts +20 -26
  390. package/dist/types.d.ts.map +1 -1
  391. package/dist/visual-enhancement.d.ts +30 -1
  392. package/dist/visual-enhancement.d.ts.map +1 -1
  393. package/dist/visual-enhancement.js +44 -12
  394. package/dist/visual-enhancement.js.map +1 -1
  395. package/package.json +3 -3
  396. package/dist/post-processor.d.ts +0 -60
  397. package/dist/post-processor.d.ts.map +0 -1
  398. package/dist/post-processor.js +0 -353
  399. package/dist/post-processor.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { MathUtils } from './math.js';
5
+ /** Reproject a pick pixel/depth pair through a reverse-Z view projection. */
6
+ export function unprojectPickSample(viewProj, pickX, pickY, width, height, depth) {
7
+ if (!Number.isFinite(depth) || depth <= 0)
8
+ return null;
9
+ const ndcX = ((pickX + 0.5) / width) * 2 - 1;
10
+ const ndcY = 1 - ((pickY + 0.5) / height) * 2;
11
+ const inverse = MathUtils.invert({ m: viewProj });
12
+ return inverse ? MathUtils.transformPoint(inverse, { x: ndcX, y: ndcY, z: depth }) : null;
13
+ }
14
+ /** Restore the f64 camera translation after an RTE depth unprojection. */
15
+ export function restoreRtePickWorld(relative, snapshot) {
16
+ if (!relative)
17
+ return null;
18
+ const camera = snapshot.getCameraWorld();
19
+ return { x: relative.x + camera[0], y: relative.y + camera[1], z: relative.z + camera[2] };
20
+ }
21
+ //# sourceMappingURL=pick-world-position.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick-world-position.js","sourceRoot":"","sources":["../src/pick-world-position.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB,CACjC,QAAsB,EACtB,KAAa,EACb,KAAa,EACb,KAAa,EACb,MAAc,EACd,KAAa;IAEb,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClD,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5F,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CACjC,QAAoD,EACpD,QAA+B;IAE/B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IACzC,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Lifecycle handling for asynchronous GPU picker readbacks. */
2
+ /** Only device teardown is an expected `AbortError`; real map faults propagate. */
3
+ export declare function isReadbackAbort(err: unknown): boolean;
4
+ /** Free aborted readbacks while preserving a visible diagnostic on a live device. */
5
+ export declare function releaseReadbacks(...buffers: GPUBuffer[]): void;
6
+ //# sourceMappingURL=picker-readbacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-readbacks.d.ts","sourceRoot":"","sources":["../src/picker-readbacks.ts"],"names":[],"mappings":"AAIA,gEAAgE;AAEhE,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAErD;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAQ9D"}
@@ -0,0 +1,20 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Lifecycle handling for asynchronous GPU picker readbacks. */
5
+ /** Only device teardown is an expected `AbortError`; real map faults propagate. */
6
+ export function isReadbackAbort(err) {
7
+ return typeof err === 'object' && err !== null && err.name === 'AbortError';
8
+ }
9
+ /** Free aborted readbacks while preserving a visible diagnostic on a live device. */
10
+ export function releaseReadbacks(...buffers) {
11
+ for (const buffer of buffers) {
12
+ try {
13
+ buffer.destroy();
14
+ }
15
+ catch (err) {
16
+ console.warn('[Picker] failed to release a readback buffer during teardown', err);
17
+ }
18
+ }
19
+ }
20
+ //# sourceMappingURL=picker-readbacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-readbacks.js","sourceRoot":"","sources":["../src/picker-readbacks.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,gEAAgE;AAEhE,mFAAmF;AACnF,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAK,GAA0B,CAAC,IAAI,KAAK,YAAY,CAAC;AACtG,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,gBAAgB,CAAC,GAAG,OAAoB;IACtD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,8DAA8D,EAAE,GAAG,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type RelativeToEyeSnapshot } from './relative-to-eye.js';
2
+ import type { Mesh, PickClipState } from './types.js';
3
+ export declare function writePickUniforms(device: GPUDevice, buffer: GPUBuffer, scratch: Float32Array, clipFlags: Uint32Array, viewProj: Float32Array, clip?: PickClipState | null): void;
4
+ export declare function writeFlatPickUniform(device: GPUDevice, buffer: GPUBuffer, scratch: Float32Array, clipFlags: Uint32Array, mesh: Mesh, snapshot: RelativeToEyeSnapshot, clip: PickClipState | null | undefined, slot: number): void;
5
+ export declare function writeInstancedPickUniforms(device: GPUDevice, buffer: GPUBuffer, scratch: Float32Array, clipFlags: Uint32Array, snapshot: RelativeToEyeSnapshot, clip?: PickClipState | null): void;
6
+ //# sourceMappingURL=picker-rte-uniforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-rte-uniforms.d.ts","sourceRoot":"","sources":["../src/picker-rte-uniforms.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,YAAY,EACtB,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC1B,IAAI,CAMN;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,WAAW,EACtB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,EACtC,IAAI,EAAE,MAAM,GACX,IAAI,CAUN;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,qBAAqB,EAC/B,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC1B,IAAI,CAQN"}
@@ -0,0 +1,41 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Dynamic uniform writers for production RTE object picking. */
5
+ import { packPickClip, packPickUniforms } from './pick-uniforms.js';
6
+ import { packRteOrigin } from './relative-to-eye.js';
7
+ import { packRteClipBox, rtePlaneDistance } from './rte-clip-space.js';
8
+ export function writePickUniforms(device, buffer, scratch, clipFlags, viewProj, clip) {
9
+ scratch.fill(0);
10
+ scratch.set(viewProj, 0);
11
+ scratch[16] = 1;
12
+ scratch[21] = 1;
13
+ scratch[26] = 1;
14
+ scratch[31] = 1;
15
+ packPickClip(clip, scratch, clipFlags, 32);
16
+ device.queue.writeBuffer(buffer, 0, scratch);
17
+ }
18
+ export function writeFlatPickUniform(device, buffer, scratch, clipFlags, mesh, snapshot, clip, slot) {
19
+ scratch.fill(0);
20
+ scratch.set(snapshot.getViewProjection().m, 0);
21
+ scratch.set(mesh.transform.m, 16);
22
+ packPickClip(clip, scratch, clipFlags, 32);
23
+ const camera = snapshot.getCameraWorld();
24
+ packRteClipBox(clip?.clipBox, camera, scratch, 32);
25
+ if (clip?.sectionPlane)
26
+ scratch[43] = rtePlaneDistance(clip.sectionPlane.distance, clip.sectionPlane.normal, camera);
27
+ snapshot.packDrawableOrigin(mesh.rteOrigin ?? [mesh.transform.m[12], mesh.transform.m[13], mesh.transform.m[14]], scratch, 48);
28
+ device.queue.writeBuffer(buffer, slot * 256, scratch);
29
+ }
30
+ export function writeInstancedPickUniforms(device, buffer, scratch, clipFlags, snapshot, clip) {
31
+ packPickUniforms(snapshot.getViewProjection().m, clip, scratch, clipFlags);
32
+ const camera = snapshot.getCameraWorld();
33
+ packRteClipBox(clip?.clipBox, camera, scratch, 16);
34
+ if (clip?.sectionPlane)
35
+ scratch[27] = rtePlaneDistance(clip.sectionPlane.distance, clip.sectionPlane.normal, camera);
36
+ packRteOrigin(camera, scratch, 32);
37
+ scratch[35] = 0;
38
+ scratch[39] = 0;
39
+ device.queue.writeBuffer(buffer, 0, scratch);
40
+ }
41
+ //# sourceMappingURL=picker-rte-uniforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-rte-uniforms.js","sourceRoot":"","sources":["../src/picker-rte-uniforms.ts"],"names":[],"mappings":"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"}
package/dist/picker.d.ts CHANGED
@@ -5,6 +5,7 @@ import { WebGPUDevice } from './device.js';
5
5
  import type { Mesh, PickResult, PickClipState } from './types.js';
6
6
  import type { InstancedTemplateGPU } from './scene.js';
7
7
  import { type PointPickNode } from './point-picker.js';
8
+ import type { RelativeToEyeSnapshot } from './relative-to-eye.js';
8
9
  /** Point-pick sizing parameters forwarded to the GPU pipeline. */
9
10
  export interface PointPickSizing {
10
11
  sizeMode: 0 | 1 | 2;
@@ -19,6 +20,7 @@ export declare class Picker {
19
20
  private pipeline;
20
21
  private instancedPickPipeline;
21
22
  private instancedPickBindGroup;
23
+ private instancedUniformBuffer;
22
24
  private depthTexture;
23
25
  private colorTexture;
24
26
  private uniformBuffer;
@@ -30,6 +32,8 @@ export declare class Picker {
30
32
  private pointPicker;
31
33
  private readonly uniformScratch;
32
34
  private readonly clipFlags;
35
+ private readonly instancedUniformScratch;
36
+ private readonly instancedClipFlags;
33
37
  constructor(device: WebGPUDevice, width?: number, height?: number);
34
38
  /**
35
39
  * Pick object at screen coordinates.
@@ -48,13 +52,8 @@ export declare class Picker {
48
52
  * null if the device dies *during* the readback, which no entry guard can
49
53
  * pre-empt (see {@link isReadbackAbort}).
50
54
  */
51
- pick(x: number, y: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray<PointPickNode>, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null): Promise<PickResult | null>;
55
+ pick(x: number, y: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray<PointPickNode>, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null, pointRteSnapshot?: RelativeToEyeSnapshot): Promise<PickResult | null>;
52
56
  updateUniforms(viewProj: Float32Array, clip?: PickClipState | null): void;
53
- /**
54
- * Pack viewProj + the last render's section plane / crop box into the shared
55
- * pick uniform and upload it. Layout + flag bits live in {@link packPickUniforms}.
56
- */
57
- private writePickUniforms;
58
57
  /**
59
58
  * Rectangle pick: render the pick pass once, then read back every
60
59
  * texel inside `[x0, y0]..[x1, y1]` and dedupe the hit set. Returns
@@ -68,7 +67,7 @@ export declare class Picker {
68
67
  * Returns an empty set once `destroy()` has run — or if the device dies
69
68
  * mid-readback — for the same reasons {@link Picker.pick} returns null.
70
69
  */
71
- pickRect(x0: number, y0: number, x1: number, y1: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray<PointPickNode>, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null): Promise<Set<number>>;
70
+ pickRect(x0: number, y0: number, x1: number, y1: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray<PointPickNode>, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null, pointRteSnapshot?: RelativeToEyeSnapshot): Promise<Set<number>>;
72
71
  /**
73
72
  * Render the picker pass into `colorTexture` + `depthTexture` and
74
73
  * return the still-open command encoder so the caller can append a
@@ -1 +1 @@
1
- {"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../src/picker.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAiC,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8EtF,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,qBAAqB,CAAkC;IAC/D,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,eAAe,CAAY;IACnC,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAkB;IACnC,uFAAuF;IACvF,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAA4B;IAI/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuD;gBAErE,MAAM,EAAE,YAAY,EAAE,KAAK,GAAE,MAAU,EAAE,MAAM,GAAE,MAAU;IAiQvE;;;;;;;;;;;;;;;;OAgBG;IACG,IAAI,CACR,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,EAAE,EACd,QAAQ,EAAE,YAAY,EACtB,UAAU,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,EACzC,WAAW,CAAC,EAAE,eAAe,EAC7B,kBAAkB,CAAC,EAAE,SAAS,oBAAoB,EAAE,EACpD,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC1B,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAyF7B,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI;IAIzE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;;;;;;;;;;;OAYG;IACG,QAAQ,CACZ,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,EAAE,EACd,QAAQ,EAAE,YAAY,EACtB,UAAU,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,EACzC,WAAW,CAAC,EAAE,eAAe,EAC7B,kBAAkB,CAAC,EAAE,SAAS,oBAAoB,EAAE,EACpD,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAsEvB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAmGtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA6B7B;;;;OAIG;IACH,OAAO,IAAI,IAAI;CAUhB"}
1
+ {"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../src/picker.ts"],"names":[],"mappings":"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"}
package/dist/picker.js CHANGED
@@ -3,81 +3,18 @@
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
  import { resolvePickSample, resolvePickedExpressId } from './pick-resolve.js';
5
5
  import { PointPicker, decodePickSample } from './point-picker.js';
6
- import { packPickUniforms } from './pick-uniforms.js';
7
- import { MathUtils } from './math.js';
8
- /**
9
- * Reproject a pick coordinate (px, depth in [0, 1]) into world space
10
- * using the inverse view-projection matrix.
11
- *
12
- * Reverse-Z: depth=1 is the near plane, depth=0 is far. A depth of
13
- * exactly 0 means the click missed every drawn primitive (depth was
14
- * never written, so the clear value sticks), and we return null.
15
- *
16
- * Pixel coords use the WebGPU/screen convention (origin top-left, y
17
- * increases downward); NDC y is inverted to match the camera's
18
- * projection matrix.
19
- */
20
- function unprojectPickSample(viewProj, pickX, pickY, width, height, depth) {
21
- if (!Number.isFinite(depth) || depth <= 0)
22
- return null;
23
- const ndcX = ((pickX + 0.5) / width) * 2 - 1;
24
- const ndcY = 1 - ((pickY + 0.5) / height) * 2;
25
- const inv = MathUtils.invert({ m: viewProj });
26
- if (!inv)
27
- return null;
28
- return MathUtils.transformPoint(inv, { x: ndcX, y: ndcY, z: depth });
29
- }
30
- /**
31
- * Whether a rejected `mapAsync` readback means "the GPU resource went away"
32
- * rather than "we asked for something illegal".
33
- *
34
- * WebGPU only rejects a map with `AbortError` when the thing being mapped
35
- * stops existing: the buffer is destroyed or unmapped before the map settles,
36
- * or the device/instance behind it is destroyed or lost. The pick path never
37
- * touches its readback buffers before the map settles, so for us that reduces
38
- * to "the device is gone" — Chromium words it
39
- * `AbortError: … A valid external Instance reference no longer exists.` (#1901).
40
- *
41
- * The entry guards in `pick()` / `pickRect()` (and `Renderer.pickPathAlive()`)
42
- * stop a pick that STARTS on a dead device, but they cannot close the window
43
- * between `queue.submit()` and the map settling: a pick that was perfectly
44
- * legal when it started is still aborted if the canvas unmounts, the model
45
- * reloads (`Renderer.destroy()` ends in `device.destroy()`), or the driver
46
- * resets while the readback is in flight. Nothing on that path can handle the
47
- * rejection — the DOM listeners that reach it are `async` functions nobody
48
- * awaits — so it escapes as an unhandled rejection.
49
- *
50
- * Real faults are NOT covered here: a validation failure (already-mapped
51
- * buffer, bad usage flags, out-of-range range) rejects with `OperationError`,
52
- * which still propagates.
53
- */
54
- function isReadbackAbort(err) {
55
- return typeof err === 'object' && err !== null && err.name === 'AbortError';
56
- }
57
- /**
58
- * Free readback buffers on the aborted path. The device may already be gone,
59
- * in which case `destroy()` is a no-op — or throws on some backends, which
60
- * must not turn a handled teardown back into an escaping error.
61
- */
62
- function releaseReadbacks(...buffers) {
63
- for (const buffer of buffers) {
64
- try {
65
- buffer.destroy();
66
- }
67
- catch (err) {
68
- // Non-fatal: the device is already gone and the buffer died with it.
69
- // Surfaced rather than swallowed, per the no-silent-catch house rule —
70
- // this firing on a LIVE device would mean a real teardown bug.
71
- console.warn('[Picker] failed to release a readback buffer during teardown', err);
72
- }
73
- }
74
- }
6
+ import { restoreRtePickWorld, unprojectPickSample } from './pick-world-position.js';
7
+ import { writeFlatPickUniform, writeInstancedPickUniforms, writePickUniforms, } from './picker-rte-uniforms.js';
8
+ import { isReadbackAbort, releaseReadbacks } from './picker-readbacks.js';
9
+ import { relativeToEyeWgsl } from './shaders/relative-to-eye.wgsl.js';
10
+ import { uploadInstancedRteDeltas } from './instanced-rte.js';
75
11
  export class Picker {
76
12
  device;
77
13
  webgpuDevice;
78
14
  pipeline;
79
15
  instancedPickPipeline = null; // GPU-instancing: pick pass for instanced occurrences; null if the backend rejected it
80
16
  instancedPickBindGroup = null;
17
+ instancedUniformBuffer;
81
18
  depthTexture;
82
19
  colorTexture;
83
20
  uniformBuffer;
@@ -87,11 +24,13 @@ export class Picker {
87
24
  /** Set by `destroy()`; makes it idempotent and turns `pick`/`pickRect` into no-ops. */
88
25
  destroyed = false;
89
26
  pointPicker = null;
90
- // Reused scratch for the 32-float (128-byte) uniform block: viewProj +
91
- // clipBoxMin/Max + sectionPlane + clipFlags. `clipFlags` is a u32 view aliasing
92
- // floats 28-31 (byte 112): bit 0 = sectionEnabled, bit 1 = flipped, bit 2 = clipBox.
93
- uniformScratch = new Float32Array(32);
94
- clipFlags = new Uint32Array(this.uniformScratch.buffer, 112, 4);
27
+ // Flat meshes each bind a dynamic 256-byte slot: RTE view projection +
28
+ // model linear transform + clip state + split drawable origin. A single
29
+ // uniform rewritten in a loop would make every draw observe the last mesh.
30
+ uniformScratch = new Float32Array(64);
31
+ clipFlags = new Uint32Array(this.uniformScratch.buffer, 44 * 4, 4);
32
+ instancedUniformScratch = new Float32Array(40);
33
+ instancedClipFlags = new Uint32Array(this.instancedUniformScratch.buffer, 112, 4);
95
34
  constructor(device, width = 1, height = 1) {
96
35
  this.webgpuDevice = device;
97
36
  this.device = device.getDevice();
@@ -109,12 +48,15 @@ export class Picker {
109
48
  // point for hover tooltips / measurements.
110
49
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
111
50
  });
112
- // Uniform buffer: viewProj (16 floats) + clipBoxMin (vec4) + clipBoxMax (vec4)
113
- // + sectionPlane (vec4) + clipFlags (vec4<u32>) = 32 floats = 128 bytes. The
114
- // picker mirrors the main render's section plane + crop box so clipped-away
115
- // geometry is unpickable, not just invisible.
51
+ // One dynamically-offset uniform slot per flat mesh. The buffer carries
52
+ // `maxMeshes` slots so the command encoder can bind the immutable payload
53
+ // for each draw after all queue writes have completed.
116
54
  this.uniformBuffer = this.device.createBuffer({
117
- size: 128,
55
+ size: this.maxMeshes * 256,
56
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
57
+ });
58
+ this.instancedUniformBuffer = this.device.createBuffer({
59
+ size: 160,
118
60
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
119
61
  });
120
62
  // Create storage buffer for expressIds (one u32 per mesh, +1 encoding)
@@ -126,12 +68,16 @@ export class Picker {
126
68
  // Create picker shader that uses storage buffer for per-object expressId
127
69
  const shaderModule = this.device.createShaderModule({
128
70
  code: `
71
+ ${relativeToEyeWgsl}
129
72
  struct Uniforms {
130
- viewProj: mat4x4<f32>,
73
+ viewProj: mat4x4<f32>, // translation-free RTE projection
74
+ model: mat4x4<f32>, // linear transform; translation lives in originHigh/Low
131
75
  clipBoxMin: vec4<f32>, // xyz = min corner (world), w = pad
132
76
  clipBoxMax: vec4<f32>, // xyz = max corner (world), w = pad
133
77
  sectionPlane: vec4<f32>, // xyz = plane normal, w = plane distance
134
78
  clipFlags: vec4<u32>, // x: bit0 sectionEnabled, bit1 flipped, bit2 clipBox
79
+ originHigh: vec4<f32>,
80
+ originLow: vec4<f32>,
135
81
  }
136
82
  @binding(0) @group(0) var<uniform> uniforms: Uniforms;
137
83
  @binding(1) @group(0) var<storage, read> expressIds: array<u32>;
@@ -150,9 +96,10 @@ export class Picker {
150
96
  @vertex
151
97
  fn vs_main(input: VertexInput, @builtin(instance_index) instanceIndex: u32) -> VertexOutput {
152
98
  var output: VertexOutput;
153
- // Identity transform - positions are already in world space
154
- output.position = uniforms.viewProj * vec4<f32>(input.position, 1.0);
155
- output.worldPos = input.position;
99
+ let linear = (uniforms.model * vec4<f32>(input.position, 0.0)).xyz;
100
+ let relative = rteWorldPosition(linear, RteDrawableUniform(uniforms.originHigh, uniforms.originLow)).xyz;
101
+ output.position = uniforms.viewProj * vec4<f32>(relative, 1.0);
102
+ output.worldPos = relative;
156
103
  // Look up expressId from storage buffer using instance index
157
104
  output.objectId = expressIds[instanceIndex];
158
105
  return output;
@@ -181,7 +128,12 @@ export class Picker {
181
128
  `,
182
129
  });
183
130
  this.pipeline = this.device.createRenderPipeline({
184
- layout: 'auto',
131
+ layout: this.device.createPipelineLayout({ bindGroupLayouts: [this.device.createBindGroupLayout({
132
+ entries: [
133
+ { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform', hasDynamicOffset: true, minBindingSize: 224 } },
134
+ { binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },
135
+ ],
136
+ })] }),
185
137
  vertex: {
186
138
  module: shaderModule,
187
139
  entryPoint: 'vs_main',
@@ -213,14 +165,13 @@ export class Picker {
213
165
  depthCompare: 'greater', // Reverse-Z: greater instead of less
214
166
  },
215
167
  });
216
- // Create bind group using the pipeline's auto-generated layout
217
- // IMPORTANT: Must use getBindGroupLayout() when pipeline uses layout: 'auto'
168
+ // Dynamic uniform offset selects the mesh-specific RTE origin/transform.
218
169
  this.bindGroup = this.device.createBindGroup({
219
170
  layout: this.pipeline.getBindGroupLayout(0),
220
171
  entries: [
221
172
  {
222
173
  binding: 0,
223
- resource: { buffer: this.uniformBuffer },
174
+ resource: { buffer: this.uniformBuffer, size: 224 },
224
175
  },
225
176
  {
226
177
  binding: 1,
@@ -236,12 +187,15 @@ export class Picker {
236
187
  // storage buffer — the id rides the instance buffer per occurrence.
237
188
  const instancedPickModule = this.device.createShaderModule({
238
189
  code: `
190
+ ${relativeToEyeWgsl}
239
191
  struct Uniforms {
240
192
  viewProj: mat4x4<f32>,
241
193
  clipBoxMin: vec4<f32>, // xyz = min corner (world), w = pad
242
194
  clipBoxMax: vec4<f32>, // xyz = max corner (world), w = pad
243
195
  sectionPlane: vec4<f32>, // xyz = plane normal, w = plane distance
244
196
  clipFlags: vec4<u32>, // x: bit0 sectionEnabled, bit1 flipped, bit2 clipBox
197
+ cameraHigh: vec4<f32>,
198
+ cameraLow: vec4<f32>,
245
199
  }
246
200
  @binding(0) @group(0) var<uniform> uniforms: Uniforms;
247
201
  struct VertexInput { @location(0) position: vec3<f32> }
@@ -252,6 +206,8 @@ export class Picker {
252
206
  @location(6) m3: vec4<f32>,
253
207
  @location(7) instEntityId: u32,
254
208
  @location(8) instFlags: u32,
209
+ @location(9) anchorHigh: vec4<f32>,
210
+ @location(10) anchorLow: vec4<f32>,
255
211
  }
256
212
  struct VertexOutput {
257
213
  @builtin(position) position: vec4<f32>,
@@ -263,9 +219,10 @@ export class Picker {
263
219
  fn vs_main(input: VertexInput, inst: InstanceInput) -> VertexOutput {
264
220
  var output: VertexOutput;
265
221
  let m = mat4x4<f32>(inst.m0, inst.m1, inst.m2, inst.m3);
266
- let world = m * vec4<f32>(input.position, 1.0);
267
- output.position = uniforms.viewProj * world;
268
- output.worldPos = world.xyz;
222
+ let linear = (m * vec4<f32>(input.position, 0.0)).xyz;
223
+ let relative = rteWorldPosition(linear, RteDrawableUniform(inst.anchorHigh, inst.anchorLow)).xyz;
224
+ output.position = uniforms.viewProj * vec4<f32>(relative, 1.0);
225
+ output.worldPos = relative;
269
226
  // bit 30 = instanced marker; express id in the low 30 bits.
270
227
  output.objectId = 0x40000000u | (inst.instEntityId & 0x3FFFFFFFu);
271
228
  output.instFlags = inst.instFlags;
@@ -311,9 +268,10 @@ export class Picker {
311
268
  buffers: [
312
269
  // slot 0: template vertex (28B pos+norm+entityId) — only position read.
313
270
  { arrayStride: 28, attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' }] },
314
- // slot 1: per-instance (88B) — mat4 + entityId + flags (colour ignored here).
271
+ // slot 1: V2 per-instance record — mat4 + id/colour/flags +
272
+ // CPU-packed drawable-minus-camera lanes.
315
273
  {
316
- arrayStride: 88,
274
+ arrayStride: 120,
317
275
  stepMode: 'instance',
318
276
  attributes: [
319
277
  { shaderLocation: 3, offset: 0, format: 'float32x4' },
@@ -322,6 +280,8 @@ export class Picker {
322
280
  { shaderLocation: 6, offset: 48, format: 'float32x4' },
323
281
  { shaderLocation: 7, offset: 64, format: 'uint32' },
324
282
  { shaderLocation: 8, offset: 84, format: 'uint32' },
283
+ { shaderLocation: 9, offset: 88, format: 'float32x4' },
284
+ { shaderLocation: 10, offset: 104, format: 'float32x4' },
325
285
  ],
326
286
  },
327
287
  ],
@@ -332,7 +292,7 @@ export class Picker {
332
292
  });
333
293
  this.instancedPickBindGroup = this.device.createBindGroup({
334
294
  layout: this.instancedPickPipeline.getBindGroupLayout(0),
335
- entries: [{ binding: 0, resource: { buffer: this.uniformBuffer } }],
295
+ entries: [{ binding: 0, resource: { buffer: this.instancedUniformBuffer } }],
336
296
  });
337
297
  }
338
298
  catch (err) {
@@ -358,10 +318,10 @@ export class Picker {
358
318
  * null if the device dies *during* the readback, which no entry guard can
359
319
  * pre-empt (see {@link isReadbackAbort}).
360
320
  */
361
- async pick(x, y, width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip) {
321
+ async pick(x, y, width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip, pointRteSnapshot) {
362
322
  if (this.destroyed)
363
323
  return null;
364
- const encoder = this.renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip);
324
+ const encoder = this.renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip, pointRteSnapshot);
365
325
  // Clamp the texel origin to the texture bounds. Math.floor(x/y) can
366
326
  // be -1 or equal to width/height on border clicks (and on
367
327
  // pointer-captured drags that leave the canvas), and either makes
@@ -426,21 +386,19 @@ export class Picker {
426
386
  // [0, 1] (1 = near, 0 = far) — same NDC convention as the camera
427
387
  // raycaster, so MathUtils.transformPoint with the inverse viewProj
428
388
  // gives the world hit position directly.
429
- const worldXYZ = unprojectPickSample(viewProj, sampleX, sampleY, width, height, depth);
389
+ // Flat meshes, points and instanced occurrences all rasterise in the
390
+ // captured RTE frame. Decode depth with that same immutable projection.
391
+ const rteDecoded = decoded.kind === 'mesh' || decoded.kind === 'point' || decoded.kind === 'instanced';
392
+ const projectedWorld = unprojectPickSample(rteDecoded && pointRteSnapshot ? pointRteSnapshot.getViewProjection().m : viewProj, sampleX, sampleY, width, height, depth);
393
+ const worldXYZ = rteDecoded && pointRteSnapshot
394
+ ? restoreRtePickWorld(projectedWorld, pointRteSnapshot)
395
+ : projectedWorld;
430
396
  // Which entity (and which representation item) the sample landed on is a
431
397
  // pure lookup — see resolvePickSample.
432
398
  return resolvePickSample(decoded, meshes, pointNodes, worldXYZ);
433
399
  }
434
400
  updateUniforms(viewProj, clip) {
435
- this.writePickUniforms(viewProj, clip);
436
- }
437
- /**
438
- * Pack viewProj + the last render's section plane / crop box into the shared
439
- * pick uniform and upload it. Layout + flag bits live in {@link packPickUniforms}.
440
- */
441
- writePickUniforms(viewProj, clip) {
442
- packPickUniforms(viewProj, clip, this.uniformScratch, this.clipFlags);
443
- this.device.queue.writeBuffer(this.uniformBuffer, 0, this.uniformScratch);
401
+ writePickUniforms(this.device, this.uniformBuffer, this.uniformScratch, this.clipFlags, viewProj, clip);
444
402
  }
445
403
  /**
446
404
  * Rectangle pick: render the pick pass once, then read back every
@@ -455,7 +413,7 @@ export class Picker {
455
413
  * Returns an empty set once `destroy()` has run — or if the device dies
456
414
  * mid-readback — for the same reasons {@link Picker.pick} returns null.
457
415
  */
458
- async pickRect(x0, y0, x1, y1, width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip) {
416
+ async pickRect(x0, y0, x1, y1, width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip, pointRteSnapshot) {
459
417
  if (this.destroyed)
460
418
  return new Set();
461
419
  // Normalise + clip rect to texture bounds.
@@ -467,7 +425,7 @@ export class Picker {
467
425
  const rectH = hy - ly + 1;
468
426
  if (rectW <= 0 || rectH <= 0)
469
427
  return new Set();
470
- const encoder = this.renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip);
428
+ const encoder = this.renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip, pointRteSnapshot);
471
429
  // copyTextureToBuffer requires bytesPerRow to be a multiple of 256.
472
430
  // r32uint = 4 bytes per texel. Round up to nearest 256.
473
431
  const rawRowBytes = rectW * 4;
@@ -530,7 +488,7 @@ export class Picker {
530
488
  * `copyTextureToBuffer` for either a single texel (`pick`) or a
531
489
  * whole rect (`pickRect`) before submitting.
532
490
  */
533
- renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip) {
491
+ renderPickPass(width, height, meshes, viewProj, pointNodes, pointSizing, instancedTemplates, clip, pointRteSnapshot) {
534
492
  if (this.colorTexture.width !== width || this.colorTexture.height !== height) {
535
493
  this.colorTexture.destroy();
536
494
  this.depthTexture.destroy();
@@ -569,7 +527,6 @@ export class Picker {
569
527
  if (meshes.length > this.maxMeshes) {
570
528
  this.resizeExpressIdBuffer(meshes.length);
571
529
  }
572
- this.writePickUniforms(viewProj, clip);
573
530
  const meshIndexArray = new Uint32Array(meshes.length);
574
531
  for (let i = 0; i < meshes.length; i++) {
575
532
  if (meshes[i])
@@ -577,11 +534,20 @@ export class Picker {
577
534
  }
578
535
  this.device.queue.writeBuffer(this.expressIdBuffer, 0, meshIndexArray);
579
536
  pass.setPipeline(this.pipeline);
580
- pass.setBindGroup(0, this.bindGroup);
581
537
  for (let i = 0; i < meshes.length; i++) {
582
538
  const mesh = meshes[i];
583
539
  if (!mesh)
584
540
  continue;
541
+ if (pointRteSnapshot) {
542
+ writeFlatPickUniform(this.device, this.uniformBuffer, this.uniformScratch, this.clipFlags, mesh, pointRteSnapshot, clip, i);
543
+ }
544
+ else {
545
+ // Compatibility for direct Picker callers that predate RTE snapshots.
546
+ // Renderer/PickingManager always supplies one so production draws use
547
+ // the per-mesh immutable RTE slots above.
548
+ writePickUniforms(this.device, this.uniformBuffer, this.uniformScratch, this.clipFlags, viewProj, clip);
549
+ }
550
+ pass.setBindGroup(0, this.bindGroup, [i * 256]);
585
551
  pass.setVertexBuffer(0, mesh.vertexBuffer);
586
552
  pass.setIndexBuffer(mesh.indexBuffer, 'uint32');
587
553
  pass.drawIndexed(mesh.indexCount, 1, 0, 0, i);
@@ -589,7 +555,9 @@ export class Picker {
589
555
  // GPU-instanced occurrences — drawn into the SAME r32uint + depth target so
590
556
  // occlusion is shared with flat meshes/points. The shader writes
591
557
  // (bit30 | express id) per occurrence; the decoder returns the entity.
592
- if (instancedTemplates && instancedTemplates.length > 0 && this.instancedPickPipeline && this.instancedPickBindGroup) {
558
+ if (instancedTemplates && instancedTemplates.length > 0 && this.instancedPickPipeline && this.instancedPickBindGroup && pointRteSnapshot) {
559
+ uploadInstancedRteDeltas(this.device, instancedTemplates, pointRteSnapshot.getCameraWorld());
560
+ writeInstancedPickUniforms(this.device, this.instancedUniformBuffer, this.instancedUniformScratch, this.instancedClipFlags, pointRteSnapshot, clip);
593
561
  pass.setPipeline(this.instancedPickPipeline);
594
562
  pass.setBindGroup(0, this.instancedPickBindGroup);
595
563
  for (const it of instancedTemplates) {
@@ -604,14 +572,13 @@ export class Picker {
604
572
  this.pointPicker = new PointPicker(this.webgpuDevice);
605
573
  }
606
574
  const sz = pointSizing ?? { sizeMode: 0, worldRadius: 0.02, pointSizePx: 4 };
607
- // Point clouds are section-clipped on render, so the point picker must clip
608
- // on the same plane (the crop box does not clip points, on render or here).
575
+ // Point clouds share both RTE section and crop discards with their colour pass.
609
576
  this.pointPicker.drawIntoPass(pass, pointNodes, viewProj, { width, height }, {
610
577
  sizeMode: sz.sizeMode,
611
578
  worldRadius: sz.worldRadius,
612
579
  pointSizePx: sz.pointSizePx,
613
580
  clickTolerancePx: sz.clickTolerancePx ?? 2,
614
- }, clip?.sectionPlane ?? null);
581
+ }, clip?.sectionPlane ?? null, pointRteSnapshot, clip?.clipBox ?? null);
615
582
  }
616
583
  pass.end();
617
584
  return encoder;
@@ -622,6 +589,7 @@ export class Picker {
622
589
  resizeExpressIdBuffer(newSize) {
623
590
  // Destroy old buffer
624
591
  this.expressIdBuffer.destroy();
592
+ this.uniformBuffer.destroy();
625
593
  // Increase maxMeshes with 50% headroom for future growth
626
594
  this.maxMeshes = Math.ceil(newSize * 1.5);
627
595
  // Create new buffer
@@ -629,13 +597,17 @@ export class Picker {
629
597
  size: this.maxMeshes * 4, // 4 bytes per u32
630
598
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
631
599
  });
600
+ this.uniformBuffer = this.device.createBuffer({
601
+ size: this.maxMeshes * 256,
602
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
603
+ });
632
604
  // Recreate bind group with new buffer
633
605
  this.bindGroup = this.device.createBindGroup({
634
606
  layout: this.pipeline.getBindGroupLayout(0),
635
607
  entries: [
636
608
  {
637
609
  binding: 0,
638
- resource: { buffer: this.uniformBuffer },
610
+ resource: { buffer: this.uniformBuffer, size: 224 },
639
611
  },
640
612
  {
641
613
  binding: 1,
@@ -656,6 +628,7 @@ export class Picker {
656
628
  this.colorTexture.destroy();
657
629
  this.depthTexture.destroy();
658
630
  this.uniformBuffer.destroy();
631
+ this.instancedUniformBuffer.destroy();
659
632
  this.expressIdBuffer.destroy();
660
633
  this.pointPicker?.destroy();
661
634
  this.pointPicker = null;