@fps-games/editor 0.2.1-beta.1 → 0.2.1-beta.2

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 (245) hide show
  1. package/dist/agent-bridge/capabilities/ui-regions.d.ts.map +1 -1
  2. package/dist/agent-bridge/capabilities/ui-regions.js +16 -0
  3. package/dist/agent-bridge/capabilities/ui-regions.js.map +1 -1
  4. package/dist/build-info.json +43 -43
  5. package/dist/internal/material-preview.d.ts +22 -0
  6. package/dist/internal/material-preview.d.ts.map +1 -0
  7. package/dist/internal/material-preview.js +186 -0
  8. package/dist/internal/material-preview.js.map +1 -0
  9. package/dist/internal/project-model-preview.d.ts +4 -0
  10. package/dist/internal/project-model-preview.d.ts.map +1 -0
  11. package/dist/internal/project-model-preview.js +359 -0
  12. package/dist/internal/project-model-preview.js.map +1 -0
  13. package/dist/local-editor-agent-context.d.ts +12 -1
  14. package/dist/local-editor-agent-context.d.ts.map +1 -1
  15. package/dist/local-editor-agent-context.js +47 -0
  16. package/dist/local-editor-agent-context.js.map +1 -1
  17. package/dist/local-editor-harness.d.ts +15 -2
  18. package/dist/local-editor-harness.d.ts.map +1 -1
  19. package/dist/local-editor-harness.js +310 -21
  20. package/dist/local-editor-harness.js.map +1 -1
  21. package/dist/local-editor-tools.d.ts +1 -0
  22. package/dist/local-editor-tools.d.ts.map +1 -1
  23. package/dist/local-editor-tools.js +3 -0
  24. package/dist/local-editor-tools.js.map +1 -1
  25. package/dist/playable-local-editor-host.d.ts +4 -0
  26. package/dist/playable-local-editor-host.d.ts.map +1 -1
  27. package/dist/playable-local-editor-host.js +27 -0
  28. package/dist/playable-local-editor-host.js.map +1 -1
  29. package/dist/playable-product-scene-capabilities.d.ts.map +1 -1
  30. package/dist/playable-product-scene-capabilities.js +9 -3
  31. package/dist/playable-product-scene-capabilities.js.map +1 -1
  32. package/dist/playable-standard-project.d.ts.map +1 -1
  33. package/dist/playable-standard-project.js +5 -2
  34. package/dist/playable-standard-project.js.map +1 -1
  35. package/node_modules/@fps-games/babylon-renderer/package.json +7 -7
  36. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +24 -0
  37. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -1
  38. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +10 -1
  39. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  40. package/node_modules/@fps-games/editor-babylon/dist/projection.js +96 -1
  41. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  42. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.d.ts.map +1 -1
  43. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.js +85 -22
  44. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.js.map +1 -1
  45. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.d.ts +2 -0
  46. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.d.ts.map +1 -1
  47. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.js +150 -4
  48. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.js.map +1 -1
  49. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts +1 -0
  50. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts.map +1 -1
  51. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js +249 -15
  52. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js.map +1 -1
  53. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts +1 -1
  54. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts.map +1 -1
  55. package/node_modules/@fps-games/editor-babylon/dist/types.js.map +1 -1
  56. package/node_modules/@fps-games/editor-babylon/package.json +6 -6
  57. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +5 -0
  58. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  59. package/node_modules/@fps-games/editor-browser/dist/index.js +3 -0
  60. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  61. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.d.ts +35 -0
  62. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.d.ts.map +1 -0
  63. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.js +136 -0
  64. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.js.map +1 -0
  65. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.d.ts +46 -0
  66. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.d.ts.map +1 -0
  67. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.js +283 -0
  68. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.js.map +1 -0
  69. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.d.ts +12 -0
  70. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.d.ts.map +1 -0
  71. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.js +67 -0
  72. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.js.map +1 -0
  73. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.d.ts +6 -0
  74. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.d.ts.map +1 -0
  75. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.js +9 -0
  76. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.js.map +1 -0
  77. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.d.ts +7 -0
  78. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.d.ts.map +1 -0
  79. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.js +20 -0
  80. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.js.map +1 -0
  81. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.d.ts +9 -0
  82. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.d.ts.map +1 -0
  83. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.js +219 -0
  84. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.js.map +1 -0
  85. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.d.ts +14 -0
  86. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.d.ts.map +1 -0
  87. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.js +42 -0
  88. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.js.map +1 -0
  89. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -1
  90. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +2 -0
  91. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -1
  92. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.d.ts +27 -0
  93. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.d.ts.map +1 -0
  94. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.js +288 -0
  95. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.js.map +1 -0
  96. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  97. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  98. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +29 -0
  99. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  100. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +20 -1
  101. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  102. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +321 -60
  103. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  104. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +2 -1
  105. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -1
  106. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +4 -2
  107. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -1
  108. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +63 -3
  109. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  110. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.js.map +1 -1
  111. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +9 -0
  112. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
  113. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +88 -16
  114. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
  115. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +2 -1
  116. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  117. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +1463 -356
  118. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  119. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.d.ts +13 -0
  120. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.d.ts.map +1 -0
  121. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.js +15 -0
  122. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.js.map +1 -0
  123. package/node_modules/@fps-games/editor-browser/package.json +7 -7
  124. package/node_modules/@fps-games/editor-core/dist/editor-tools.d.ts +1 -0
  125. package/node_modules/@fps-games/editor-core/dist/editor-tools.d.ts.map +1 -1
  126. package/node_modules/@fps-games/editor-core/dist/editor-tools.js +3 -1
  127. package/node_modules/@fps-games/editor-core/dist/editor-tools.js.map +1 -1
  128. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +11 -2
  129. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
  130. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +12 -1
  131. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
  132. package/node_modules/@fps-games/editor-core/package.json +6 -6
  133. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  134. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts +1 -0
  135. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
  136. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +5 -0
  137. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
  138. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.d.ts +1 -1
  139. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.d.ts.map +1 -1
  140. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.js +1 -1
  141. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.js.map +1 -1
  142. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.d.ts.map +1 -1
  143. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.js +15 -1
  144. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.js.map +1 -1
  145. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.d.ts.map +1 -1
  146. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.js +3 -0
  147. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.js.map +1 -1
  148. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.d.ts +6 -1
  149. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.d.ts.map +1 -1
  150. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.js.map +1 -1
  151. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +1 -0
  152. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  153. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +1 -0
  154. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  155. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.d.ts +4 -0
  156. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.d.ts.map +1 -1
  157. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.js +10 -1
  158. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.js.map +1 -1
  159. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.d.ts +4 -0
  160. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.d.ts.map +1 -0
  161. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.js +4 -0
  162. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.js.map +1 -0
  163. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.d.ts +4 -0
  164. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.d.ts.map +1 -0
  165. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.js +86 -0
  166. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.js.map +1 -0
  167. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.d.ts +9 -0
  168. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.d.ts.map +1 -0
  169. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.js +76 -0
  170. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.js.map +1 -0
  171. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.d.ts +34 -0
  172. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.d.ts.map +1 -0
  173. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.js +2 -0
  174. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.js.map +1 -0
  175. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.d.ts +4 -0
  176. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.d.ts.map +1 -1
  177. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js +40 -0
  178. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js.map +1 -1
  179. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts +1 -0
  180. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts.map +1 -1
  181. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js +1 -0
  182. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js.map +1 -1
  183. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.d.ts +1 -0
  184. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.d.ts.map +1 -1
  185. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.js +94 -0
  186. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.js.map +1 -1
  187. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.d.ts +14 -0
  188. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.d.ts.map +1 -0
  189. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.js +101 -0
  190. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.js.map +1 -0
  191. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.d.ts +23 -0
  192. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.d.ts.map +1 -0
  193. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.js +180 -0
  194. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.js.map +1 -0
  195. package/node_modules/@fps-games/editor-playable-sdk/package.json +6 -6
  196. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +23 -3
  197. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
  198. package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
  199. package/node_modules/@fps-games/editor-protocol/package.json +2 -2
  200. package/node_modules/@fps-games/editor-tooling/package.json +3 -3
  201. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.d.ts.map +1 -1
  202. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.js +103 -10
  203. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.js.map +1 -1
  204. package/node_modules/@fps-games/editor-ui/package.json +1 -1
  205. package/node_modules/@fps-games/playable-assets/package.json +1 -1
  206. package/node_modules/@fps-games/playable-contracts/package.json +1 -1
  207. package/node_modules/@fps-games/playable-rendering/package.json +2 -2
  208. package/node_modules/@fps-games/playable-runtime/package.json +12 -12
  209. package/node_modules/@fps-games/playable-runtime-data/package.json +4 -4
  210. package/node_modules/@fps-games/playable-scene/package.json +2 -2
  211. package/node_modules/@fps-games/plugin-api/package.json +1 -1
  212. package/node_modules/@fps-games/plugin-assets/dist/version.d.ts +1 -1
  213. package/node_modules/@fps-games/plugin-assets/dist/version.js +1 -1
  214. package/node_modules/@fps-games/plugin-assets/dist/version.js.map +1 -1
  215. package/node_modules/@fps-games/plugin-assets/package.json +5 -5
  216. package/node_modules/@fps-games/plugin-hierarchy/dist/version.d.ts +1 -1
  217. package/node_modules/@fps-games/plugin-hierarchy/dist/version.js +1 -1
  218. package/node_modules/@fps-games/plugin-hierarchy/dist/version.js.map +1 -1
  219. package/node_modules/@fps-games/plugin-hierarchy/package.json +5 -5
  220. package/node_modules/@fps-games/plugin-host/package.json +2 -2
  221. package/node_modules/@fps-games/plugin-markers/dist/version.d.ts +1 -1
  222. package/node_modules/@fps-games/plugin-markers/dist/version.js +1 -1
  223. package/node_modules/@fps-games/plugin-markers/dist/version.js.map +1 -1
  224. package/node_modules/@fps-games/plugin-markers/package.json +5 -5
  225. package/node_modules/@fps-games/plugin-materials/dist/version.d.ts +1 -1
  226. package/node_modules/@fps-games/plugin-materials/dist/version.js +1 -1
  227. package/node_modules/@fps-games/plugin-materials/dist/version.js.map +1 -1
  228. package/node_modules/@fps-games/plugin-materials/package.json +5 -5
  229. package/node_modules/@fps-games/plugin-rendering/dist/version.d.ts +1 -1
  230. package/node_modules/@fps-games/plugin-rendering/dist/version.js +1 -1
  231. package/node_modules/@fps-games/plugin-rendering/dist/version.js.map +1 -1
  232. package/node_modules/@fps-games/plugin-rendering/package.json +5 -5
  233. package/node_modules/@fps-games/plugin-scene/dist/version.d.ts +1 -1
  234. package/node_modules/@fps-games/plugin-scene/dist/version.js +1 -1
  235. package/node_modules/@fps-games/plugin-scene/dist/version.js.map +1 -1
  236. package/node_modules/@fps-games/plugin-scene/package.json +5 -5
  237. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.d.ts +1 -1
  238. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js +1 -1
  239. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js.map +1 -1
  240. package/node_modules/@fps-games/plugin-shadow-map-experiment/package.json +5 -5
  241. package/node_modules/@fps-games/plugin-shadows/dist/version.d.ts +1 -1
  242. package/node_modules/@fps-games/plugin-shadows/dist/version.js +1 -1
  243. package/node_modules/@fps-games/plugin-shadows/dist/version.js.map +1 -1
  244. package/node_modules/@fps-games/plugin-shadows/package.json +7 -7
  245. package/package.json +22 -22
@@ -1 +1 @@
1
- {"version":3,"file":"scene-view-spatial-overlay-controller.d.ts","sourceRoot":"","sources":["../src/scene-view-spatial-overlay-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,6BAA6B,EAI7B,iCAAiC,EAClC,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EACV,oBAAoB,EACpB,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,+CAA+C;IAC9D,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,mCAAmC;IAClD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAED,MAAM,WAAW,wCAAwC;IACvD,OAAO,CAAC,KAAK,EAAE,mCAAmC,GAAG,iCAAiC,CAAC;IACvF,OAAO,IAAI,IAAI,CAAC;CACjB;AAsDD,wBAAgB,8CAA8C,CAC5D,OAAO,EAAE,+CAA+C,GACvD,wCAAwC,CAY1C;AAED,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,+CAA+C,EACxD,KAAK,EAAE,mCAAmC,GACzC,iCAAiC,CA2DnC;AAwGD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvE"}
1
+ {"version":3,"file":"scene-view-spatial-overlay-controller.d.ts","sourceRoot":"","sources":["../src/scene-view-spatial-overlay-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,6BAA6B,EAI7B,iCAAiC,EAClC,MAAM,wBAAwB,CAAC;AAIhC,OAAO,KAAK,EACV,oBAAoB,EACpB,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,+CAA+C;IAC9D,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,mCAAmC;IAClD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,6BAA6B,CAAC;CACzC;AAED,MAAM,WAAW,wCAAwC;IACvD,OAAO,CAAC,KAAK,EAAE,mCAAmC,GAAG,iCAAiC,CAAC;IACvF,OAAO,IAAI,IAAI,CAAC;CACjB;AAwDD,wBAAgB,8CAA8C,CAC5D,OAAO,EAAE,+CAA+C,GACvD,wCAAwC,CAY1C;AAED,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,+CAA+C,EACxD,KAAK,EAAE,mCAAmC,GACzC,iCAAiC,CA0DnC;AA8KD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvE"}
@@ -1,5 +1,7 @@
1
1
  import { createEmptyEditorViewportSpatialOverlayState, } from '@fps-games/editor-core';
2
2
  const MIN_LABEL_EDGE_LENGTH_PX = 34;
3
+ const MAX_BOUNDS_CORNER_LENGTH_PX = 34;
4
+ const BOUNDS_CORNER_EDGE_RATIO = 0.22;
3
5
  const BOUNDS_EDGES = [
4
6
  { id: 'x-y0-z0', axis: 'x', start: 'min-min-min', end: 'max-min-min' },
5
7
  { id: 'x-y1-z0', axis: 'x', start: 'min-max-min', end: 'max-max-min' },
@@ -43,9 +45,7 @@ export function createEditorViewportSpatialOverlayState(options, input) {
43
45
  const labels = [];
44
46
  if (input.settings.bounds) {
45
47
  for (const edge of BOUNDS_EDGES) {
46
- const line = createOverlayLine(edge, cornerMap);
47
- if (line)
48
- lines.push(line);
48
+ lines.push(...createBoundsCornerLines(edge, cornerMap));
49
49
  }
50
50
  }
51
51
  if (input.settings.dimensions) {
@@ -93,16 +93,18 @@ export function createEditorViewportSpatialOverlayState(options, input) {
93
93
  };
94
94
  }
95
95
  function projectBoundsCorners(options, bounds) {
96
- const corners = [
97
- ['min-min-min', { x: bounds.min.x, y: bounds.min.y, z: bounds.min.z }],
98
- ['max-min-min', { x: bounds.max.x, y: bounds.min.y, z: bounds.min.z }],
99
- ['min-max-min', { x: bounds.min.x, y: bounds.max.y, z: bounds.min.z }],
100
- ['max-max-min', { x: bounds.max.x, y: bounds.max.y, z: bounds.min.z }],
101
- ['min-min-max', { x: bounds.min.x, y: bounds.min.y, z: bounds.max.z }],
102
- ['max-min-max', { x: bounds.max.x, y: bounds.min.y, z: bounds.max.z }],
103
- ['min-max-max', { x: bounds.min.x, y: bounds.max.y, z: bounds.max.z }],
104
- ['max-max-max', { x: bounds.max.x, y: bounds.max.y, z: bounds.max.z }],
105
- ];
96
+ const corners = bounds.oriented
97
+ ? createOrientedBoundsCorners(bounds.oriented)
98
+ : [
99
+ ['min-min-min', { x: bounds.min.x, y: bounds.min.y, z: bounds.min.z }],
100
+ ['max-min-min', { x: bounds.max.x, y: bounds.min.y, z: bounds.min.z }],
101
+ ['min-max-min', { x: bounds.min.x, y: bounds.max.y, z: bounds.min.z }],
102
+ ['max-max-min', { x: bounds.max.x, y: bounds.max.y, z: bounds.min.z }],
103
+ ['min-min-max', { x: bounds.min.x, y: bounds.min.y, z: bounds.max.z }],
104
+ ['max-min-max', { x: bounds.max.x, y: bounds.min.y, z: bounds.max.z }],
105
+ ['min-max-max', { x: bounds.min.x, y: bounds.max.y, z: bounds.max.z }],
106
+ ['max-max-max', { x: bounds.max.x, y: bounds.max.y, z: bounds.max.z }],
107
+ ];
106
108
  const projected = [];
107
109
  for (const [key, world] of corners) {
108
110
  const screen = projectWorldPoint(options, world);
@@ -112,6 +114,32 @@ function projectBoundsCorners(options, bounds) {
112
114
  }
113
115
  return projected;
114
116
  }
117
+ function createOrientedBoundsCorners(oriented) {
118
+ const corner = (xSign, ySign, zSign) => ({
119
+ x: oriented.center.x
120
+ + oriented.axes.x.x * oriented.size.x * 0.5 * xSign
121
+ + oriented.axes.y.x * oriented.size.y * 0.5 * ySign
122
+ + oriented.axes.z.x * oriented.size.z * 0.5 * zSign,
123
+ y: oriented.center.y
124
+ + oriented.axes.x.y * oriented.size.x * 0.5 * xSign
125
+ + oriented.axes.y.y * oriented.size.y * 0.5 * ySign
126
+ + oriented.axes.z.y * oriented.size.z * 0.5 * zSign,
127
+ z: oriented.center.z
128
+ + oriented.axes.x.z * oriented.size.x * 0.5 * xSign
129
+ + oriented.axes.y.z * oriented.size.y * 0.5 * ySign
130
+ + oriented.axes.z.z * oriented.size.z * 0.5 * zSign,
131
+ });
132
+ return [
133
+ ['min-min-min', corner(-1, -1, -1)],
134
+ ['max-min-min', corner(1, -1, -1)],
135
+ ['min-max-min', corner(-1, 1, -1)],
136
+ ['max-max-min', corner(1, 1, -1)],
137
+ ['min-min-max', corner(-1, -1, 1)],
138
+ ['max-min-max', corner(1, -1, 1)],
139
+ ['min-max-max', corner(-1, 1, 1)],
140
+ ['max-max-max', corner(1, 1, 1)],
141
+ ];
142
+ }
115
143
  function projectWorldPoint(options, point) {
116
144
  const Vector3 = options.babylon.Vector3;
117
145
  const Matrix = options.babylon.Matrix;
@@ -119,7 +147,12 @@ function projectWorldPoint(options, point) {
119
147
  const camera = scene.activeCamera ?? scene.cameraToUseForPointers ?? null;
120
148
  const canvas = scene.getEngine?.().getRenderingCanvas?.();
121
149
  const viewport = camera?.viewport?.toGlobal?.(scene.getEngine?.().getRenderWidth?.() ?? canvas?.width ?? 0, scene.getEngine?.().getRenderHeight?.() ?? canvas?.height ?? 0);
122
- const transformMatrix = scene.getTransformMatrix?.();
150
+ // Overlay projection can run before the next Babylon render after a camera
151
+ // command. Refresh the camera matrices here so the DOM overlay never renders
152
+ // one frame behind the scene view.
153
+ camera?.getViewMatrix?.(true);
154
+ camera?.getProjectionMatrix?.(true);
155
+ const transformMatrix = camera?.getTransformationMatrix?.() ?? scene.getTransformMatrix?.();
123
156
  if (!Vector3?.Project || !Matrix?.Identity || !camera || !canvas || !viewport || !transformMatrix)
124
157
  return null;
125
158
  const canvasRect = canvas.getBoundingClientRect();
@@ -135,16 +168,35 @@ function projectWorldPoint(options, point) {
135
168
  return null;
136
169
  return { x, y, depth };
137
170
  }
138
- function createOverlayLine(edge, corners) {
171
+ function createBoundsCornerLines(edge, corners) {
139
172
  const start = corners.get(edge.start)?.screen;
140
173
  const end = corners.get(edge.end)?.screen;
141
174
  if (!start || !end)
142
- return null;
175
+ return [];
176
+ const screenLength = Math.hypot(end.x - start.x, end.y - start.y);
177
+ if (!Number.isFinite(screenLength) || screenLength < 1)
178
+ return [];
179
+ const segmentLength = Math.min(MAX_BOUNDS_CORNER_LENGTH_PX, screenLength * BOUNDS_CORNER_EDGE_RATIO);
180
+ const ratio = segmentLength / screenLength;
181
+ const startEnd = interpolateScreenPoint(start, end, ratio);
182
+ const endStart = interpolateScreenPoint(end, start, ratio);
183
+ return [{
184
+ id: `${edge.id}:start`,
185
+ kind: 'bounds',
186
+ start: { ...start },
187
+ end: startEnd,
188
+ }, {
189
+ id: `${edge.id}:end`,
190
+ kind: 'bounds',
191
+ start: { ...end },
192
+ end: endStart,
193
+ }];
194
+ }
195
+ function interpolateScreenPoint(start, end, ratio) {
143
196
  return {
144
- id: edge.id,
145
- kind: 'bounds',
146
- start: { ...start },
147
- end: { ...end },
197
+ x: start.x + (end.x - start.x) * ratio,
198
+ y: start.y + (end.y - start.y) * ratio,
199
+ depth: start.depth + (end.depth - start.depth) * ratio,
148
200
  };
149
201
  }
150
202
  function createEdgeLabel(edge, corners, bounds, kind) {
@@ -159,8 +211,8 @@ function createEdgeLabel(edge, corners, bounds, kind) {
159
211
  id: `${kind}-${edge.id}`,
160
212
  kind,
161
213
  text: kind === 'dimension'
162
- ? `${edge.axis.toUpperCase()} ${formatNumber(bounds.size[edge.axis])}`
163
- : formatNumber(bounds.size[edge.axis]),
214
+ ? `${edge.axis.toUpperCase()} ${formatNumber((bounds.oriented?.size ?? bounds.size)[edge.axis])}`
215
+ : formatNumber((bounds.oriented?.size ?? bounds.size)[edge.axis]),
164
216
  x: (start.x + end.x) / 2,
165
217
  y: (start.y + end.y) / 2,
166
218
  };
@@ -171,6 +223,17 @@ function cloneBounds(bounds) {
171
223
  max: { ...bounds.max },
172
224
  center: { ...bounds.center },
173
225
  size: { ...bounds.size },
226
+ ...(bounds.oriented ? {
227
+ oriented: {
228
+ center: { ...bounds.oriented.center },
229
+ size: { ...bounds.oriented.size },
230
+ axes: {
231
+ x: { ...bounds.oriented.axes.x },
232
+ y: { ...bounds.oriented.axes.y },
233
+ z: { ...bounds.oriented.axes.z },
234
+ },
235
+ },
236
+ } : {}),
174
237
  };
175
238
  }
176
239
  export function formatEditorViewportOverlayNumber(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"scene-view-spatial-overlay-controller.js","sourceRoot":"","sources":["../src/scene-view-spatial-overlay-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EditorTransformVec3,\n EditorViewportBounds,\n EditorViewportOverlaySettings,\n EditorViewportSpatialOverlayLabel,\n EditorViewportSpatialOverlayLine,\n EditorViewportSpatialOverlayMarker,\n EditorViewportSpatialOverlayState,\n} from '@fps-games/editor-core';\nimport {\n createEmptyEditorViewportSpatialOverlayState,\n} from '@fps-games/editor-core';\nimport type {\n BabylonRuntimeGlobal,\n RuntimeScene,\n} from './types';\n\nexport interface BabylonSceneViewSpatialOverlayControllerOptions {\n babylon: BabylonRuntimeGlobal;\n scene: RuntimeScene;\n}\n\nexport interface BabylonSceneViewSpatialOverlayInput {\n nodeId: string | null;\n bounds: EditorViewportBounds | null;\n anchor: EditorTransformVec3 | null;\n settings: EditorViewportOverlaySettings;\n}\n\nexport interface BabylonSceneViewSpatialOverlayController {\n compute(input: BabylonSceneViewSpatialOverlayInput): EditorViewportSpatialOverlayState;\n dispose(): void;\n}\n\ninterface ProjectedCorner {\n key: BoundsCornerKey;\n world: EditorTransformVec3;\n screen: ProjectedPoint;\n}\n\ninterface ProjectedPoint {\n x: number;\n y: number;\n depth: number;\n}\n\ntype BoundsCornerKey =\n | 'min-min-min'\n | 'max-min-min'\n | 'min-max-min'\n | 'max-max-min'\n | 'min-min-max'\n | 'max-min-max'\n | 'min-max-max'\n | 'max-max-max';\n\ninterface BoundsEdge {\n id: string;\n axis: 'x' | 'y' | 'z';\n start: BoundsCornerKey;\n end: BoundsCornerKey;\n}\n\nconst MIN_LABEL_EDGE_LENGTH_PX = 34;\n\nconst BOUNDS_EDGES = [\n { id: 'x-y0-z0', axis: 'x', start: 'min-min-min', end: 'max-min-min' },\n { id: 'x-y1-z0', axis: 'x', start: 'min-max-min', end: 'max-max-min' },\n { id: 'x-y0-z1', axis: 'x', start: 'min-min-max', end: 'max-min-max' },\n { id: 'x-y1-z1', axis: 'x', start: 'min-max-max', end: 'max-max-max' },\n { id: 'y-x0-z0', axis: 'y', start: 'min-min-min', end: 'min-max-min' },\n { id: 'y-x1-z0', axis: 'y', start: 'max-min-min', end: 'max-max-min' },\n { id: 'y-x0-z1', axis: 'y', start: 'min-min-max', end: 'min-max-max' },\n { id: 'y-x1-z1', axis: 'y', start: 'max-min-max', end: 'max-max-max' },\n { id: 'z-x0-y0', axis: 'z', start: 'min-min-min', end: 'min-min-max' },\n { id: 'z-x1-y0', axis: 'z', start: 'max-min-min', end: 'max-min-max' },\n { id: 'z-x0-y1', axis: 'z', start: 'min-max-min', end: 'min-max-max' },\n { id: 'z-x1-y1', axis: 'z', start: 'max-max-min', end: 'max-max-max' },\n] as const satisfies readonly BoundsEdge[];\n\nconst DIMENSION_EDGES = [\n BOUNDS_EDGES[0],\n BOUNDS_EDGES[4],\n BOUNDS_EDGES[8],\n] as const satisfies readonly BoundsEdge[];\n\nexport function createBabylonSceneViewSpatialOverlayController(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n): BabylonSceneViewSpatialOverlayController {\n let disposed = false;\n\n return {\n compute(input) {\n if (disposed) return createEmptyEditorViewportSpatialOverlayState();\n return createEditorViewportSpatialOverlayState(options, input);\n },\n dispose() {\n disposed = true;\n },\n };\n}\n\nexport function createEditorViewportSpatialOverlayState(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n input: BabylonSceneViewSpatialOverlayInput,\n): EditorViewportSpatialOverlayState {\n if (!input.nodeId || !input.bounds) return createEmptyEditorViewportSpatialOverlayState();\n const projectedCorners = projectBoundsCorners(options, input.bounds);\n if (!projectedCorners) return createEmptyEditorViewportSpatialOverlayState();\n const cornerMap = new Map(projectedCorners.map(corner => [corner.key, corner]));\n const lines: EditorViewportSpatialOverlayLine[] = [];\n const labels: EditorViewportSpatialOverlayLabel[] = [];\n\n if (input.settings.bounds) {\n for (const edge of BOUNDS_EDGES) {\n const line = createOverlayLine(edge, cornerMap);\n if (line) lines.push(line);\n }\n }\n\n if (input.settings.dimensions) {\n for (const edge of DIMENSION_EDGES) {\n const label = createEdgeLabel(edge, cornerMap, input.bounds, 'dimension');\n if (label) labels.push(label);\n }\n }\n\n if (input.settings.edgeLengths) {\n for (const edge of BOUNDS_EDGES) {\n const label = createEdgeLabel(edge, cornerMap, input.bounds, 'edge-length');\n if (label) labels.push(label);\n }\n }\n\n const markers: EditorViewportSpatialOverlayMarker[] = [];\n if (input.settings.anchor && input.anchor) {\n const anchor = projectWorldPoint(options, input.anchor);\n if (anchor) {\n const label = `Anchor ${formatVec3(input.anchor)}`;\n markers.push({\n id: 'anchor',\n kind: 'anchor',\n position: anchor,\n label,\n });\n labels.push({\n id: 'anchor-label',\n kind: 'anchor',\n text: label,\n x: anchor.x,\n y: anchor.y - 18,\n });\n }\n }\n\n return {\n active: lines.length > 0 || labels.length > 0 || markers.length > 0,\n nodeId: input.nodeId,\n bounds: cloneBounds(input.bounds),\n anchor: input.anchor ? { ...input.anchor } : null,\n lines,\n labels,\n markers,\n };\n}\n\nfunction projectBoundsCorners(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n bounds: EditorViewportBounds,\n): ProjectedCorner[] | null {\n const corners: Array<[BoundsCornerKey, EditorTransformVec3]> = [\n ['min-min-min', { x: bounds.min.x, y: bounds.min.y, z: bounds.min.z }],\n ['max-min-min', { x: bounds.max.x, y: bounds.min.y, z: bounds.min.z }],\n ['min-max-min', { x: bounds.min.x, y: bounds.max.y, z: bounds.min.z }],\n ['max-max-min', { x: bounds.max.x, y: bounds.max.y, z: bounds.min.z }],\n ['min-min-max', { x: bounds.min.x, y: bounds.min.y, z: bounds.max.z }],\n ['max-min-max', { x: bounds.max.x, y: bounds.min.y, z: bounds.max.z }],\n ['min-max-max', { x: bounds.min.x, y: bounds.max.y, z: bounds.max.z }],\n ['max-max-max', { x: bounds.max.x, y: bounds.max.y, z: bounds.max.z }],\n ];\n const projected: ProjectedCorner[] = [];\n for (const [key, world] of corners) {\n const screen = projectWorldPoint(options, world);\n if (!screen) return null;\n projected.push({ key, world, screen });\n }\n return projected;\n}\n\nfunction projectWorldPoint(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n point: EditorTransformVec3,\n): ProjectedPoint | null {\n const Vector3 = options.babylon.Vector3 as any;\n const Matrix = (options.babylon as any).Matrix;\n const scene = options.scene;\n const camera = scene.activeCamera ?? (scene as any).cameraToUseForPointers ?? null;\n const canvas = scene.getEngine?.().getRenderingCanvas?.() as HTMLCanvasElement | null | undefined;\n const viewport = camera?.viewport?.toGlobal?.(\n scene.getEngine?.().getRenderWidth?.() ?? canvas?.width ?? 0,\n scene.getEngine?.().getRenderHeight?.() ?? canvas?.height ?? 0,\n );\n const transformMatrix = scene.getTransformMatrix?.();\n if (!Vector3?.Project || !Matrix?.Identity || !camera || !canvas || !viewport || !transformMatrix) return null;\n const canvasRect = canvas.getBoundingClientRect();\n const renderWidth = Math.max(1, Number(scene.getEngine?.().getRenderWidth?.() ?? canvas.width ?? canvasRect.width));\n const renderHeight = Math.max(1, Number(scene.getEngine?.().getRenderHeight?.() ?? canvas.height ?? canvasRect.height));\n const cssScaleX = canvasRect.width / renderWidth;\n const cssScaleY = canvasRect.height / renderHeight;\n const projected = Vector3.Project(\n new Vector3(point.x, point.y, point.z),\n Matrix.Identity(),\n transformMatrix,\n viewport,\n );\n const x = canvasRect.left + Number(projected?.x) * cssScaleX;\n const y = canvasRect.top + Number(projected?.y) * cssScaleY;\n const depth = Number(projected?.z);\n if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(depth)) return null;\n return { x, y, depth };\n}\n\nfunction createOverlayLine(\n edge: BoundsEdge,\n corners: Map<BoundsCornerKey, ProjectedCorner>,\n): EditorViewportSpatialOverlayLine | null {\n const start = corners.get(edge.start)?.screen;\n const end = corners.get(edge.end)?.screen;\n if (!start || !end) return null;\n return {\n id: edge.id,\n kind: 'bounds',\n start: { ...start },\n end: { ...end },\n };\n}\n\nfunction createEdgeLabel(\n edge: BoundsEdge,\n corners: Map<BoundsCornerKey, ProjectedCorner>,\n bounds: EditorViewportBounds,\n kind: 'dimension' | 'edge-length',\n): EditorViewportSpatialOverlayLabel | null {\n const start = corners.get(edge.start)?.screen;\n const end = corners.get(edge.end)?.screen;\n if (!start || !end) return null;\n const screenLength = Math.hypot(end.x - start.x, end.y - start.y);\n if (screenLength < MIN_LABEL_EDGE_LENGTH_PX) return null;\n return {\n id: `${kind}-${edge.id}`,\n kind,\n text: kind === 'dimension'\n ? `${edge.axis.toUpperCase()} ${formatNumber(bounds.size[edge.axis])}`\n : formatNumber(bounds.size[edge.axis]),\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n };\n}\n\nfunction cloneBounds(bounds: EditorViewportBounds): EditorViewportBounds {\n return {\n min: { ...bounds.min },\n max: { ...bounds.max },\n center: { ...bounds.center },\n size: { ...bounds.size },\n };\n}\n\nexport function formatEditorViewportOverlayNumber(value: number): string {\n return formatNumber(value);\n}\n\nfunction formatVec3(value: EditorTransformVec3): string {\n return `(${formatNumber(value.x)}, ${formatNumber(value.y)}, ${formatNumber(value.z)})`;\n}\n\nfunction formatNumber(value: number): string {\n if (!Number.isFinite(value)) return '0';\n const rounded = Math.abs(value) < 0.005 ? 0 : value;\n return rounded.toFixed(2).replace(/\\.?0+$/, '');\n}\n"]}
1
+ {"version":3,"file":"scene-view-spatial-overlay-controller.js","sourceRoot":"","sources":["../src/scene-view-spatial-overlay-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EditorTransformVec3,\n EditorViewportBounds,\n EditorViewportOverlaySettings,\n EditorViewportSpatialOverlayLabel,\n EditorViewportSpatialOverlayLine,\n EditorViewportSpatialOverlayMarker,\n EditorViewportSpatialOverlayState,\n} from '@fps-games/editor-core';\nimport {\n createEmptyEditorViewportSpatialOverlayState,\n} from '@fps-games/editor-core';\nimport type {\n BabylonRuntimeGlobal,\n RuntimeScene,\n} from './types';\n\nexport interface BabylonSceneViewSpatialOverlayControllerOptions {\n babylon: BabylonRuntimeGlobal;\n scene: RuntimeScene;\n}\n\nexport interface BabylonSceneViewSpatialOverlayInput {\n nodeId: string | null;\n bounds: EditorViewportBounds | null;\n anchor: EditorTransformVec3 | null;\n settings: EditorViewportOverlaySettings;\n}\n\nexport interface BabylonSceneViewSpatialOverlayController {\n compute(input: BabylonSceneViewSpatialOverlayInput): EditorViewportSpatialOverlayState;\n dispose(): void;\n}\n\ninterface ProjectedCorner {\n key: BoundsCornerKey;\n world: EditorTransformVec3;\n screen: ProjectedPoint;\n}\n\ninterface ProjectedPoint {\n x: number;\n y: number;\n depth: number;\n}\n\ntype BoundsCornerKey =\n | 'min-min-min'\n | 'max-min-min'\n | 'min-max-min'\n | 'max-max-min'\n | 'min-min-max'\n | 'max-min-max'\n | 'min-max-max'\n | 'max-max-max';\n\ninterface BoundsEdge {\n id: string;\n axis: 'x' | 'y' | 'z';\n start: BoundsCornerKey;\n end: BoundsCornerKey;\n}\n\nconst MIN_LABEL_EDGE_LENGTH_PX = 34;\nconst MAX_BOUNDS_CORNER_LENGTH_PX = 34;\nconst BOUNDS_CORNER_EDGE_RATIO = 0.22;\n\nconst BOUNDS_EDGES = [\n { id: 'x-y0-z0', axis: 'x', start: 'min-min-min', end: 'max-min-min' },\n { id: 'x-y1-z0', axis: 'x', start: 'min-max-min', end: 'max-max-min' },\n { id: 'x-y0-z1', axis: 'x', start: 'min-min-max', end: 'max-min-max' },\n { id: 'x-y1-z1', axis: 'x', start: 'min-max-max', end: 'max-max-max' },\n { id: 'y-x0-z0', axis: 'y', start: 'min-min-min', end: 'min-max-min' },\n { id: 'y-x1-z0', axis: 'y', start: 'max-min-min', end: 'max-max-min' },\n { id: 'y-x0-z1', axis: 'y', start: 'min-min-max', end: 'min-max-max' },\n { id: 'y-x1-z1', axis: 'y', start: 'max-min-max', end: 'max-max-max' },\n { id: 'z-x0-y0', axis: 'z', start: 'min-min-min', end: 'min-min-max' },\n { id: 'z-x1-y0', axis: 'z', start: 'max-min-min', end: 'max-min-max' },\n { id: 'z-x0-y1', axis: 'z', start: 'min-max-min', end: 'min-max-max' },\n { id: 'z-x1-y1', axis: 'z', start: 'max-max-min', end: 'max-max-max' },\n] as const satisfies readonly BoundsEdge[];\n\nconst DIMENSION_EDGES = [\n BOUNDS_EDGES[0],\n BOUNDS_EDGES[4],\n BOUNDS_EDGES[8],\n] as const satisfies readonly BoundsEdge[];\n\nexport function createBabylonSceneViewSpatialOverlayController(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n): BabylonSceneViewSpatialOverlayController {\n let disposed = false;\n\n return {\n compute(input) {\n if (disposed) return createEmptyEditorViewportSpatialOverlayState();\n return createEditorViewportSpatialOverlayState(options, input);\n },\n dispose() {\n disposed = true;\n },\n };\n}\n\nexport function createEditorViewportSpatialOverlayState(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n input: BabylonSceneViewSpatialOverlayInput,\n): EditorViewportSpatialOverlayState {\n if (!input.nodeId || !input.bounds) return createEmptyEditorViewportSpatialOverlayState();\n const projectedCorners = projectBoundsCorners(options, input.bounds);\n if (!projectedCorners) return createEmptyEditorViewportSpatialOverlayState();\n const cornerMap = new Map(projectedCorners.map(corner => [corner.key, corner]));\n const lines: EditorViewportSpatialOverlayLine[] = [];\n const labels: EditorViewportSpatialOverlayLabel[] = [];\n\n if (input.settings.bounds) {\n for (const edge of BOUNDS_EDGES) {\n lines.push(...createBoundsCornerLines(edge, cornerMap));\n }\n }\n\n if (input.settings.dimensions) {\n for (const edge of DIMENSION_EDGES) {\n const label = createEdgeLabel(edge, cornerMap, input.bounds, 'dimension');\n if (label) labels.push(label);\n }\n }\n\n if (input.settings.edgeLengths) {\n for (const edge of BOUNDS_EDGES) {\n const label = createEdgeLabel(edge, cornerMap, input.bounds, 'edge-length');\n if (label) labels.push(label);\n }\n }\n\n const markers: EditorViewportSpatialOverlayMarker[] = [];\n if (input.settings.anchor && input.anchor) {\n const anchor = projectWorldPoint(options, input.anchor);\n if (anchor) {\n const label = `Anchor ${formatVec3(input.anchor)}`;\n markers.push({\n id: 'anchor',\n kind: 'anchor',\n position: anchor,\n label,\n });\n labels.push({\n id: 'anchor-label',\n kind: 'anchor',\n text: label,\n x: anchor.x,\n y: anchor.y - 18,\n });\n }\n }\n\n return {\n active: lines.length > 0 || labels.length > 0 || markers.length > 0,\n nodeId: input.nodeId,\n bounds: cloneBounds(input.bounds),\n anchor: input.anchor ? { ...input.anchor } : null,\n lines,\n labels,\n markers,\n };\n}\n\nfunction projectBoundsCorners(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n bounds: EditorViewportBounds,\n): ProjectedCorner[] | null {\n const corners: Array<[BoundsCornerKey, EditorTransformVec3]> = bounds.oriented\n ? createOrientedBoundsCorners(bounds.oriented)\n : [\n ['min-min-min', { x: bounds.min.x, y: bounds.min.y, z: bounds.min.z }],\n ['max-min-min', { x: bounds.max.x, y: bounds.min.y, z: bounds.min.z }],\n ['min-max-min', { x: bounds.min.x, y: bounds.max.y, z: bounds.min.z }],\n ['max-max-min', { x: bounds.max.x, y: bounds.max.y, z: bounds.min.z }],\n ['min-min-max', { x: bounds.min.x, y: bounds.min.y, z: bounds.max.z }],\n ['max-min-max', { x: bounds.max.x, y: bounds.min.y, z: bounds.max.z }],\n ['min-max-max', { x: bounds.min.x, y: bounds.max.y, z: bounds.max.z }],\n ['max-max-max', { x: bounds.max.x, y: bounds.max.y, z: bounds.max.z }],\n ];\n const projected: ProjectedCorner[] = [];\n for (const [key, world] of corners) {\n const screen = projectWorldPoint(options, world);\n if (!screen) return null;\n projected.push({ key, world, screen });\n }\n return projected;\n}\n\nfunction createOrientedBoundsCorners(\n oriented: NonNullable<EditorViewportBounds['oriented']>,\n): Array<[BoundsCornerKey, EditorTransformVec3]> {\n const corner = (xSign: number, ySign: number, zSign: number): EditorTransformVec3 => ({\n x: oriented.center.x\n + oriented.axes.x.x * oriented.size.x * 0.5 * xSign\n + oriented.axes.y.x * oriented.size.y * 0.5 * ySign\n + oriented.axes.z.x * oriented.size.z * 0.5 * zSign,\n y: oriented.center.y\n + oriented.axes.x.y * oriented.size.x * 0.5 * xSign\n + oriented.axes.y.y * oriented.size.y * 0.5 * ySign\n + oriented.axes.z.y * oriented.size.z * 0.5 * zSign,\n z: oriented.center.z\n + oriented.axes.x.z * oriented.size.x * 0.5 * xSign\n + oriented.axes.y.z * oriented.size.y * 0.5 * ySign\n + oriented.axes.z.z * oriented.size.z * 0.5 * zSign,\n });\n return [\n ['min-min-min', corner(-1, -1, -1)],\n ['max-min-min', corner(1, -1, -1)],\n ['min-max-min', corner(-1, 1, -1)],\n ['max-max-min', corner(1, 1, -1)],\n ['min-min-max', corner(-1, -1, 1)],\n ['max-min-max', corner(1, -1, 1)],\n ['min-max-max', corner(-1, 1, 1)],\n ['max-max-max', corner(1, 1, 1)],\n ];\n}\n\nfunction projectWorldPoint(\n options: BabylonSceneViewSpatialOverlayControllerOptions,\n point: EditorTransformVec3,\n): ProjectedPoint | null {\n const Vector3 = options.babylon.Vector3 as any;\n const Matrix = (options.babylon as any).Matrix;\n const scene = options.scene;\n const camera = scene.activeCamera ?? (scene as any).cameraToUseForPointers ?? null;\n const canvas = scene.getEngine?.().getRenderingCanvas?.() as HTMLCanvasElement | null | undefined;\n const viewport = camera?.viewport?.toGlobal?.(\n scene.getEngine?.().getRenderWidth?.() ?? canvas?.width ?? 0,\n scene.getEngine?.().getRenderHeight?.() ?? canvas?.height ?? 0,\n );\n // Overlay projection can run before the next Babylon render after a camera\n // command. Refresh the camera matrices here so the DOM overlay never renders\n // one frame behind the scene view.\n camera?.getViewMatrix?.(true);\n camera?.getProjectionMatrix?.(true);\n const transformMatrix = camera?.getTransformationMatrix?.() ?? scene.getTransformMatrix?.();\n if (!Vector3?.Project || !Matrix?.Identity || !camera || !canvas || !viewport || !transformMatrix) return null;\n const canvasRect = canvas.getBoundingClientRect();\n const renderWidth = Math.max(1, Number(scene.getEngine?.().getRenderWidth?.() ?? canvas.width ?? canvasRect.width));\n const renderHeight = Math.max(1, Number(scene.getEngine?.().getRenderHeight?.() ?? canvas.height ?? canvasRect.height));\n const cssScaleX = canvasRect.width / renderWidth;\n const cssScaleY = canvasRect.height / renderHeight;\n const projected = Vector3.Project(\n new Vector3(point.x, point.y, point.z),\n Matrix.Identity(),\n transformMatrix,\n viewport,\n );\n const x = canvasRect.left + Number(projected?.x) * cssScaleX;\n const y = canvasRect.top + Number(projected?.y) * cssScaleY;\n const depth = Number(projected?.z);\n if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(depth)) return null;\n return { x, y, depth };\n}\n\nfunction createBoundsCornerLines(\n edge: BoundsEdge,\n corners: Map<BoundsCornerKey, ProjectedCorner>,\n): EditorViewportSpatialOverlayLine[] {\n const start = corners.get(edge.start)?.screen;\n const end = corners.get(edge.end)?.screen;\n if (!start || !end) return [];\n const screenLength = Math.hypot(end.x - start.x, end.y - start.y);\n if (!Number.isFinite(screenLength) || screenLength < 1) return [];\n const segmentLength = Math.min(MAX_BOUNDS_CORNER_LENGTH_PX, screenLength * BOUNDS_CORNER_EDGE_RATIO);\n const ratio = segmentLength / screenLength;\n const startEnd = interpolateScreenPoint(start, end, ratio);\n const endStart = interpolateScreenPoint(end, start, ratio);\n return [{\n id: `${edge.id}:start`,\n kind: 'bounds',\n start: { ...start },\n end: startEnd,\n }, {\n id: `${edge.id}:end`,\n kind: 'bounds',\n start: { ...end },\n end: endStart,\n }];\n}\n\nfunction interpolateScreenPoint(\n start: ProjectedPoint,\n end: ProjectedPoint,\n ratio: number,\n): ProjectedPoint {\n return {\n x: start.x + (end.x - start.x) * ratio,\n y: start.y + (end.y - start.y) * ratio,\n depth: start.depth + (end.depth - start.depth) * ratio,\n };\n}\n\nfunction createEdgeLabel(\n edge: BoundsEdge,\n corners: Map<BoundsCornerKey, ProjectedCorner>,\n bounds: EditorViewportBounds,\n kind: 'dimension' | 'edge-length',\n): EditorViewportSpatialOverlayLabel | null {\n const start = corners.get(edge.start)?.screen;\n const end = corners.get(edge.end)?.screen;\n if (!start || !end) return null;\n const screenLength = Math.hypot(end.x - start.x, end.y - start.y);\n if (screenLength < MIN_LABEL_EDGE_LENGTH_PX) return null;\n return {\n id: `${kind}-${edge.id}`,\n kind,\n text: kind === 'dimension'\n ? `${edge.axis.toUpperCase()} ${formatNumber((bounds.oriented?.size ?? bounds.size)[edge.axis])}`\n : formatNumber((bounds.oriented?.size ?? bounds.size)[edge.axis]),\n x: (start.x + end.x) / 2,\n y: (start.y + end.y) / 2,\n };\n}\n\nfunction cloneBounds(bounds: EditorViewportBounds): EditorViewportBounds {\n return {\n min: { ...bounds.min },\n max: { ...bounds.max },\n center: { ...bounds.center },\n size: { ...bounds.size },\n ...(bounds.oriented ? {\n oriented: {\n center: { ...bounds.oriented.center },\n size: { ...bounds.oriented.size },\n axes: {\n x: { ...bounds.oriented.axes.x },\n y: { ...bounds.oriented.axes.y },\n z: { ...bounds.oriented.axes.z },\n },\n },\n } : {}),\n };\n}\n\nexport function formatEditorViewportOverlayNumber(value: number): string {\n return formatNumber(value);\n}\n\nfunction formatVec3(value: EditorTransformVec3): string {\n return `(${formatNumber(value.x)}, ${formatNumber(value.y)}, ${formatNumber(value.z)})`;\n}\n\nfunction formatNumber(value: number): string {\n if (!Number.isFinite(value)) return '0';\n const rounded = Math.abs(value) < 0.005 ? 0 : value;\n return rounded.toFixed(2).replace(/\\.?0+$/, '');\n}\n"]}
@@ -55,6 +55,7 @@ export interface BabylonEditorSelectionPresentationDiagnostics {
55
55
  export interface BabylonEditorSelectionPresentationBackend {
56
56
  setSelectedMeshes(meshes: readonly any[], groups?: readonly BabylonSelectionIdentityGroup[]): void;
57
57
  setEnabled(enabled: boolean): void;
58
+ prewarm?(meshes: readonly any[]): void;
58
59
  prepareFrame(): void;
59
60
  getResourceCount(): number;
60
61
  getSceneDepthSourceKind?(): BabylonEditorSelectionSceneDepthSourceKind | null;
@@ -67,6 +68,7 @@ export interface BabylonEditorSelectionPresentationControllerOptions {
67
68
  logger?: Pick<Console, 'warn'>;
68
69
  onDiagnostic?: (diagnostic: BabylonEditorSelectionPresentationDiagnostic) => void;
69
70
  sceneDepthSourceProvider?: BabylonEditorSelectionSceneDepthSourceProvider;
71
+ prewarm?: boolean;
70
72
  createBackend?: (options: BabylonEditorSelectionPresentationControllerOptions, reportDiagnostic: (diagnostic: BabylonEditorSelectionPresentationDiagnostic) => void) => BabylonEditorSelectionPresentationBackend;
71
73
  }
72
74
  export interface BabylonEditorSelectionPresentationController {
@@ -1 +1 @@
1
- {"version":3,"file":"selection-presentation-controller.d.ts","sourceRoot":"","sources":["../src/selection-presentation-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"selection-presentation-controller.d.ts","sourceRoot":"","sources":["../src/selection-presentation-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAajF,MAAM,MAAM,8BAA8B,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACvF,MAAM,MAAM,0CAA0C,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAE9F,MAAM,WAAW,2CAA2C;IAC1D,QAAQ,CAAC,IAAI,EAAE,0CAA0C,CAAC;IAC1D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC;IAChC,UAAU,IAAI,GAAG,CAAC;IAClB,QAAQ,IAAI,IAAI,CAAC;IACjB,UAAU,IAAI,IAAI,CAAC;IACnB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,6CAA6C;IAC5D,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpD,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,mBAAmB,EAAE,GAAG,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,CAAC,UAAU,EAAE,4CAA4C,KAAK,IAAI,CAAC;CACtF;AAED,MAAM,WAAW,8CAA8C;IAC7D,OAAO,CAAC,OAAO,EAAE,6CAA6C,GAAG,2CAA2C,CAAC;CAC9G;AA4SD,MAAM,WAAW,+CAA+C;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC;IACjC,4BAA4B,CAAC,EAAE,SAAS,wCAAwC,EAAE,CAAC;CACpF;AAED,MAAM,WAAW,wCAAwC;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,SAAS,GAAG,EAAE,CAAC;CAC9B;AAED,MAAM,MAAM,gDAAgD,GACxD,+BAA+B,GAC/B,kBAAkB,GAClB,2BAA2B,GAC3B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,4CAA4C;IAC3D,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,6CAA6C;IAC5D,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,0CAA0C,GAAG,IAAI,CAAC;IACpE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,4CAA4C,GAAG,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,yCAAyC;IACxD,iBAAiB,CACf,MAAM,EAAE,SAAS,GAAG,EAAE,EACtB,MAAM,CAAC,EAAE,SAAS,6BAA6B,EAAE,GAChD,IAAI,CAAC;IACR,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,CAAC,MAAM,EAAE,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;IACvC,YAAY,IAAI,IAAI,CAAC;IACrB,gBAAgB,IAAI,MAAM,CAAC;IAC3B,uBAAuB,CAAC,IAAI,0CAA0C,GAAG,IAAI,CAAC;IAC9E,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,mDAAmD;IAClE,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpD,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,4CAA4C,KAAK,IAAI,CAAC;IAClF,wBAAwB,CAAC,EAAE,8CAA8C,CAAC;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,CACd,OAAO,EAAE,mDAAmD,EAC5D,gBAAgB,EAAE,CAAC,UAAU,EAAE,4CAA4C,KAAK,IAAI,KACjF,yCAAyC,CAAC;CAChD;AAED,MAAM,WAAW,4CAA4C;IAC3D,mBAAmB,CAAC,IAAI,EAAE,+CAA+C,GAAG,IAAI,CAAC;IACjF,mBAAmB,CAAC,IAAI,EAAE,+CAA+C,GAAG,IAAI,CAAC;IACjF,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,aAAa,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrD,YAAY,IAAI,IAAI,CAAC;IACrB,cAAc,IAAI,6CAA6C,CAAC;IAChE,OAAO,IAAI,IAAI,CAAC;CACjB;AA2CD,wBAAgB,kDAAkD,CAChE,OAAO,EAAE,mDAAmD,GAC3D,4CAA4C,CA8K9C;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,+CAA+C,CAAC,EAC3E,SAAS,EAAE,oBAAoB,GAC9B,GAAG,EAAE,CA+BP;AAsrBD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACnD,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,SAAS,GAAG,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,SAAoC,GAC5C,8BAA8B,CAmDhC;AA6CD,eAAO,MAAM,wCAAwC,EAAE,8CAItD,CAAC"}
@@ -317,6 +317,8 @@ export function createBabylonEditorSelectionPresentationController(options) {
317
317
  let failed = false;
318
318
  let disposed = false;
319
319
  let selectedMeshCount = 0;
320
+ let prewarmed = false;
321
+ const prewarmedMeshes = new Set();
320
322
  let lastDiagnostic = null;
321
323
  const reportDiagnostic = (diagnostic) => {
322
324
  lastDiagnostic = diagnostic;
@@ -348,6 +350,7 @@ export function createBabylonEditorSelectionPresentationController(options) {
348
350
  const syncBackendMembership = () => {
349
351
  if (disposed)
350
352
  return;
353
+ const previousSelectedMeshCount = selectedMeshCount;
351
354
  const groups = selection.selectedIds
352
355
  .map(selectionId => ({
353
356
  selectionId,
@@ -365,6 +368,12 @@ export function createBabylonEditorSelectionPresentationController(options) {
365
368
  }
366
369
  selectedMeshCount = meshes.length;
367
370
  if (meshes.length === 0) {
371
+ // Projection attaches nodes incrementally. Once a cold-start prewarm has
372
+ // begun, later empty-selection membership updates must not cancel it
373
+ // before the first warm frame has rendered. A real deselection still
374
+ // clears the backend because it transitions from a non-empty selection.
375
+ if (prewarmed && previousSelectedMeshCount === 0)
376
+ return;
368
377
  backend?.setSelectedMeshes([], groups);
369
378
  backend?.setEnabled(false);
370
379
  return;
@@ -388,18 +397,49 @@ export function createBabylonEditorSelectionPresentationController(options) {
388
397
  });
389
398
  }
390
399
  };
400
+ const prewarmBackendIfNeeded = (node) => {
401
+ if (!options.prewarm || disposed || failed || selection.selectedIds.length > 0)
402
+ return;
403
+ const candidates = collectSelectedPresentationMeshes(new Map([[node.nodeId, node]]), { selectedIds: [node.nodeId], activeId: node.nodeId }).filter(mesh => !prewarmedMeshes.has(mesh));
404
+ if (candidates.length === 0)
405
+ return;
406
+ const nextBackend = ensureBackend();
407
+ if (!nextBackend?.prewarm)
408
+ return;
409
+ // Mark the controller before entering the backend because depth/pre-pass
410
+ // allocation can synchronously re-enter projection membership updates.
411
+ // Those empty-selection updates must observe the in-flight prewarm.
412
+ prewarmed = true;
413
+ for (const candidate of candidates)
414
+ prewarmedMeshes.add(candidate);
415
+ try {
416
+ nextBackend.prewarm(candidates);
417
+ }
418
+ catch (cause) {
419
+ for (const candidate of candidates)
420
+ prewarmedMeshes.delete(candidate);
421
+ prewarmed = prewarmedMeshes.size > 0;
422
+ reportDiagnostic({
423
+ code: 'backend-initialization-failed',
424
+ message: 'Selection silhouette prewarm failed; the first selection may compile resources on demand.',
425
+ cause,
426
+ });
427
+ }
428
+ };
391
429
  return {
392
430
  attachProjectedNode(node) {
393
431
  if (disposed)
394
432
  return;
395
433
  nodes.set(node.nodeId, node);
396
434
  syncBackendMembership();
435
+ prewarmBackendIfNeeded(node);
397
436
  },
398
437
  updateProjectedNode(node) {
399
438
  if (disposed)
400
439
  return;
401
440
  nodes.set(node.nodeId, node);
402
441
  syncBackendMembership();
442
+ prewarmBackendIfNeeded(node);
403
443
  },
404
444
  detachProjectedNode(nodeId) {
405
445
  if (disposed)
@@ -530,6 +570,11 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
530
570
  let height = 0;
531
571
  let selectionSourceRatio = MAX_SELECTION_SOURCE_DENSITY;
532
572
  let shaderNotReadyFrames = 0;
573
+ let prewarming = false;
574
+ let prewarmCleanupQueued = false;
575
+ let prewarmReadyFrameCount = 0;
576
+ let prewarmRenderedFrameCount = 0;
577
+ let prewarmAfterRenderObserver = null;
533
578
  let resourcesActive = false;
534
579
  let sceneDepthLeaseActive = false;
535
580
  let selectedDepthMapActive = false;
@@ -596,6 +641,26 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
596
641
  detachPostProcessPass(compositePass);
597
642
  detachPostProcessPass(occupancyMaskPass);
598
643
  };
644
+ const clearPrewarmAfterRenderObserver = () => {
645
+ if (prewarmAfterRenderObserver == null)
646
+ return;
647
+ scene?.onAfterRenderObservable?.remove?.(prewarmAfterRenderObserver);
648
+ prewarmAfterRenderObserver = null;
649
+ };
650
+ const finishPrewarm = () => {
651
+ if (!prewarming)
652
+ return;
653
+ prewarming = false;
654
+ clearPrewarmAfterRenderObserver();
655
+ prewarmReadyFrameCount = 0;
656
+ prewarmRenderedFrameCount = 0;
657
+ selectedMeshes = [];
658
+ selectionGroups = [];
659
+ if (selectedDepthMap)
660
+ selectedDepthMap.renderList = selectedMeshes;
661
+ enabled = false;
662
+ deactivateResources();
663
+ };
599
664
  const activateResources = () => {
600
665
  if (!enabled
601
666
  || !sceneDepthLease
@@ -645,7 +710,11 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
645
710
  pass.attached = false;
646
711
  pass.insertIndex = null;
647
712
  };
648
- const disposeCameraResources = () => {
713
+ const disposeCameraResources = (preservePrewarm = false) => {
714
+ if (!preservePrewarm) {
715
+ clearPrewarmAfterRenderObserver();
716
+ prewarming = false;
717
+ }
649
718
  deactivateResources();
650
719
  const ownedCamera = camera;
651
720
  disposePostProcessPass(compositePass, ownedCamera);
@@ -773,7 +842,9 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
773
842
  const outputWidth = Math.max(1, Number(engine.getRenderWidth?.() ?? width ?? nextWidth));
774
843
  const outputHeight = Math.max(1, Number(engine.getRenderHeight?.() ?? height ?? nextHeight));
775
844
  const presentationSize = resolveSelectionPresentationSize(engine, outputWidth, outputHeight);
776
- selectionUvBounds = computeSelectionPresentationUvBounds(babylon, scene, nextCamera, selectedMeshes, outputWidth, outputHeight, SELECTION_PRESENTATION_PADDING_PX);
845
+ selectionUvBounds = prewarming
846
+ ? [1, 1, 0, 0]
847
+ : computeSelectionPresentationUvBounds(babylon, scene, nextCamera, selectedMeshes, outputWidth, outputHeight, SELECTION_PRESENTATION_PADDING_PX);
777
848
  effect.setTexture?.('editorSelectedDepthSampler', nextSelectedMap);
778
849
  const selectedSize = nextSelectedMap.getSize?.() ?? {
779
850
  width: nextWidth * nextSelectionSourceRatio,
@@ -887,7 +958,7 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
887
958
  || !occupancyMaskPass.resource
888
959
  || !compositePass.resource
889
960
  || requiresSelectionIdentityPass() !== !!selectionIdentityPass) {
890
- disposeCameraResources();
961
+ disposeCameraResources(true);
891
962
  createCameraResources(nextCamera);
892
963
  return;
893
964
  }
@@ -932,6 +1003,18 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
932
1003
  }
933
1004
  return {
934
1005
  setSelectedMeshes(meshes, groups) {
1006
+ if (prewarming) {
1007
+ // Projected nodes can publish empty membership while the scene is
1008
+ // still being assembled. Treat that as prewarm noise; a non-empty
1009
+ // selection is the only state transition that may take ownership of
1010
+ // the warmed resources before cleanup.
1011
+ if (meshes.length === 0)
1012
+ return;
1013
+ prewarming = false;
1014
+ clearPrewarmAfterRenderObserver();
1015
+ prewarmReadyFrameCount = 0;
1016
+ prewarmRenderedFrameCount = 0;
1017
+ }
935
1018
  const requiredBefore = requiresSelectionIdentityPass();
936
1019
  selectedMeshes = [...meshes];
937
1020
  selectionGroups = groups?.map(group => ({
@@ -950,13 +1033,71 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
950
1033
  selectionIdentityPass?.setSelection(selectionGroups);
951
1034
  },
952
1035
  setEnabled(nextEnabled) {
1036
+ if (prewarming && !nextEnabled)
1037
+ return;
953
1038
  if (disposed || enabled === nextEnabled)
954
1039
  return;
955
1040
  enabled = nextEnabled;
956
1041
  if (enabled)
957
1042
  prepareFrame();
958
- else
1043
+ else {
1044
+ prewarming = false;
1045
+ clearPrewarmAfterRenderObserver();
1046
+ prewarmReadyFrameCount = 0;
1047
+ prewarmRenderedFrameCount = 0;
959
1048
  deactivateResources();
1049
+ }
1050
+ },
1051
+ prewarm(meshes) {
1052
+ if (disposed || meshes.length === 0 || (enabled && !prewarming))
1053
+ return;
1054
+ if (prewarming) {
1055
+ const mergedMeshes = [...selectedMeshes];
1056
+ const seenMeshes = new Set(mergedMeshes);
1057
+ for (const mesh of meshes)
1058
+ appendPresentationMesh(mergedMeshes, seenMeshes, mesh);
1059
+ selectedMeshes = mergedMeshes;
1060
+ if (selectedDepthMap)
1061
+ selectedDepthMap.renderList = selectedMeshes;
1062
+ prewarmReadyFrameCount = 0;
1063
+ prewarmRenderedFrameCount = 0;
1064
+ return;
1065
+ }
1066
+ selectedMeshes = [...meshes];
1067
+ selectionGroups = [];
1068
+ prewarming = true;
1069
+ prewarmReadyFrameCount = 0;
1070
+ prewarmRenderedFrameCount = 0;
1071
+ enabled = true;
1072
+ prepareFrame();
1073
+ const afterRenderObservable = scene?.onAfterRenderObservable;
1074
+ if (afterRenderObservable?.add) {
1075
+ prewarmAfterRenderObserver = afterRenderObservable.add(() => {
1076
+ prewarmRenderedFrameCount += 1;
1077
+ const selectedDepthReady = selectedDepthMap?.isReadyForRendering?.() ?? true;
1078
+ const postProcessesReady = (occupancyMaskPass.resource?.isReady?.() ?? true)
1079
+ && (compositePass.resource?.isReady?.() ?? true);
1080
+ prewarmReadyFrameCount = selectedDepthReady && postProcessesReady
1081
+ ? prewarmReadyFrameCount + 1
1082
+ : 0;
1083
+ // One readiness probe can itself trigger deferred shader work.
1084
+ // Require a second rendered frame with all resources ready before
1085
+ // detaching them from the scene.
1086
+ if (prewarmReadyFrameCount < 2 && prewarmRenderedFrameCount < 4)
1087
+ return;
1088
+ clearPrewarmAfterRenderObserver();
1089
+ if (prewarmCleanupQueued)
1090
+ return;
1091
+ prewarmCleanupQueued = true;
1092
+ void Promise.resolve().then(() => {
1093
+ prewarmCleanupQueued = false;
1094
+ finishPrewarm();
1095
+ });
1096
+ });
1097
+ }
1098
+ else {
1099
+ finishPrewarm();
1100
+ }
960
1101
  },
961
1102
  prepareFrame,
962
1103
  getResourceCount() {
@@ -983,6 +1124,11 @@ function createDepthAwareSelectionPresentationBackend(options, reportDiagnostic)
983
1124
  if (disposed)
984
1125
  return;
985
1126
  disposed = true;
1127
+ clearPrewarmAfterRenderObserver();
1128
+ prewarming = false;
1129
+ prewarmCleanupQueued = false;
1130
+ prewarmReadyFrameCount = 0;
1131
+ prewarmRenderedFrameCount = 0;
986
1132
  if (beforeRenderObserver != null)
987
1133
  beforeRenderObservable?.remove?.(beforeRenderObserver);
988
1134
  beforeRenderObserver = null;