@fps-games/editor 0.1.5-beta.5 → 0.1.7-beta.1

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 (469) hide show
  1. package/dist/agent-bridge/capabilities/assets.d.ts +8 -0
  2. package/dist/agent-bridge/capabilities/assets.d.ts.map +1 -0
  3. package/dist/agent-bridge/capabilities/assets.js +226 -0
  4. package/dist/agent-bridge/capabilities/assets.js.map +1 -0
  5. package/dist/agent-bridge/capabilities/editor-state.d.ts +5 -0
  6. package/dist/agent-bridge/capabilities/editor-state.d.ts.map +1 -0
  7. package/dist/agent-bridge/capabilities/editor-state.js +72 -0
  8. package/dist/agent-bridge/capabilities/editor-state.js.map +1 -0
  9. package/dist/agent-bridge/capabilities/host-lifecycle.d.ts +4 -0
  10. package/dist/agent-bridge/capabilities/host-lifecycle.d.ts.map +1 -0
  11. package/dist/agent-bridge/capabilities/host-lifecycle.js +87 -0
  12. package/dist/agent-bridge/capabilities/host-lifecycle.js.map +1 -0
  13. package/dist/agent-bridge/capabilities/prefabs.d.ts +5 -0
  14. package/dist/agent-bridge/capabilities/prefabs.d.ts.map +1 -0
  15. package/dist/agent-bridge/capabilities/prefabs.js +735 -0
  16. package/dist/agent-bridge/capabilities/prefabs.js.map +1 -0
  17. package/dist/agent-bridge/capabilities/scene-objects.d.ts +9 -0
  18. package/dist/agent-bridge/capabilities/scene-objects.d.ts.map +1 -0
  19. package/dist/agent-bridge/capabilities/scene-objects.js +394 -0
  20. package/dist/agent-bridge/capabilities/scene-objects.js.map +1 -0
  21. package/dist/agent-bridge/capabilities/selection.d.ts +5 -0
  22. package/dist/agent-bridge/capabilities/selection.d.ts.map +1 -0
  23. package/dist/agent-bridge/capabilities/selection.js +57 -0
  24. package/dist/agent-bridge/capabilities/selection.js.map +1 -0
  25. package/dist/agent-bridge/capabilities/shadows.d.ts +5 -0
  26. package/dist/agent-bridge/capabilities/shadows.d.ts.map +1 -0
  27. package/dist/agent-bridge/capabilities/shadows.js +1876 -0
  28. package/dist/agent-bridge/capabilities/shadows.js.map +1 -0
  29. package/dist/agent-bridge/capabilities/transform.d.ts +5 -0
  30. package/dist/agent-bridge/capabilities/transform.d.ts.map +1 -0
  31. package/dist/agent-bridge/capabilities/transform.js +162 -0
  32. package/dist/agent-bridge/capabilities/transform.js.map +1 -0
  33. package/dist/agent-bridge/capabilities/ui-regions.d.ts +4 -0
  34. package/dist/agent-bridge/capabilities/ui-regions.d.ts.map +1 -0
  35. package/dist/agent-bridge/capabilities/ui-regions.js +168 -0
  36. package/dist/agent-bridge/capabilities/ui-regions.js.map +1 -0
  37. package/dist/agent-bridge/capabilities/viewport.d.ts +5 -0
  38. package/dist/agent-bridge/capabilities/viewport.d.ts.map +1 -0
  39. package/dist/agent-bridge/capabilities/viewport.js +407 -0
  40. package/dist/agent-bridge/capabilities/viewport.js.map +1 -0
  41. package/dist/agent-bridge/capability-sources.d.ts +6 -0
  42. package/dist/agent-bridge/capability-sources.d.ts.map +1 -0
  43. package/dist/agent-bridge/capability-sources.js +26 -0
  44. package/dist/agent-bridge/capability-sources.js.map +1 -0
  45. package/dist/agent-bridge/diagnostics.d.ts +12 -0
  46. package/dist/agent-bridge/diagnostics.d.ts.map +1 -0
  47. package/dist/agent-bridge/diagnostics.js +45 -0
  48. package/dist/agent-bridge/diagnostics.js.map +1 -0
  49. package/dist/agent-bridge/index.d.ts +5 -0
  50. package/dist/agent-bridge/index.d.ts.map +1 -0
  51. package/dist/agent-bridge/index.js +5 -0
  52. package/dist/agent-bridge/index.js.map +1 -0
  53. package/dist/agent-bridge/register.d.ts +4 -0
  54. package/dist/agent-bridge/register.d.ts.map +1 -0
  55. package/dist/agent-bridge/register.js +908 -0
  56. package/dist/agent-bridge/register.js.map +1 -0
  57. package/dist/agent-bridge/shared.d.ts +189 -0
  58. package/dist/agent-bridge/shared.d.ts.map +1 -0
  59. package/dist/agent-bridge/shared.js +39 -0
  60. package/dist/agent-bridge/shared.js.map +1 -0
  61. package/dist/agent-bridge/source-types.d.ts +90 -0
  62. package/dist/agent-bridge/source-types.d.ts.map +1 -0
  63. package/dist/agent-bridge/source-types.js +2 -0
  64. package/dist/agent-bridge/source-types.js.map +1 -0
  65. package/dist/build-info.json +17 -17
  66. package/dist/local-editor-agent-actions.d.ts +8 -1
  67. package/dist/local-editor-agent-actions.d.ts.map +1 -1
  68. package/dist/local-editor-agent-actions.js +171 -12
  69. package/dist/local-editor-agent-actions.js.map +1 -1
  70. package/dist/local-editor-agent-bridge-transport.d.ts +95 -0
  71. package/dist/local-editor-agent-bridge-transport.d.ts.map +1 -0
  72. package/dist/local-editor-agent-bridge-transport.js +340 -0
  73. package/dist/local-editor-agent-bridge-transport.js.map +1 -0
  74. package/dist/local-editor-agent-bridge.d.ts +2 -0
  75. package/dist/local-editor-agent-bridge.d.ts.map +1 -0
  76. package/dist/local-editor-agent-bridge.js +2 -0
  77. package/dist/local-editor-agent-bridge.js.map +1 -0
  78. package/dist/local-editor-agent-context.d.ts +29 -1
  79. package/dist/local-editor-agent-context.d.ts.map +1 -1
  80. package/dist/local-editor-agent-context.js +403 -0
  81. package/dist/local-editor-agent-context.js.map +1 -1
  82. package/dist/local-editor-harness.d.ts +128 -6
  83. package/dist/local-editor-harness.d.ts.map +1 -1
  84. package/dist/local-editor-harness.js +2730 -151
  85. package/dist/local-editor-harness.js.map +1 -1
  86. package/dist/local-editor-marker-graph.d.ts +92 -0
  87. package/dist/local-editor-marker-graph.d.ts.map +1 -0
  88. package/dist/local-editor-marker-graph.js +1432 -0
  89. package/dist/local-editor-marker-graph.js.map +1 -0
  90. package/dist/local-editor-performance-stats.js +1 -1
  91. package/dist/local-editor-performance-stats.js.map +1 -1
  92. package/dist/playable-babylon-facade.d.ts +2 -2
  93. package/dist/playable-babylon-facade.d.ts.map +1 -1
  94. package/dist/playable-babylon-facade.js +1 -1
  95. package/dist/playable-babylon-facade.js.map +1 -1
  96. package/dist/playable-babylon-rendering.js +20 -0
  97. package/dist/playable-babylon-rendering.js.map +1 -1
  98. package/dist/playable-local-editor-host.d.ts +57 -7
  99. package/dist/playable-local-editor-host.d.ts.map +1 -1
  100. package/dist/playable-local-editor-host.js +25 -1
  101. package/dist/playable-local-editor-host.js.map +1 -1
  102. package/dist/playable-sdk.d.ts +4 -2
  103. package/dist/playable-sdk.d.ts.map +1 -1
  104. package/dist/playable-sdk.js +2 -1
  105. package/dist/playable-sdk.js.map +1 -1
  106. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.d.ts.map +1 -1
  107. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js +6 -4
  108. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js.map +1 -1
  109. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.d.ts.map +1 -1
  110. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js +103 -1
  111. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js.map +1 -1
  112. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.d.ts.map +1 -1
  113. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js +330 -27
  114. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js.map +1 -1
  115. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.d.ts.map +1 -1
  116. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js +159 -0
  117. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js.map +1 -1
  118. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js +8 -1
  119. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js.map +1 -1
  120. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts +53 -2
  121. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts.map +1 -1
  122. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js +1 -0
  123. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js.map +1 -1
  124. package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
  125. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts.map +1 -1
  126. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +11 -0
  127. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -1
  128. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts +3 -1
  129. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts.map +1 -1
  130. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js +114 -18
  131. package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js.map +1 -1
  132. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts +1 -0
  133. package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts.map +1 -1
  134. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js +3 -0
  135. package/node_modules/@fps-games/editor-babylon/dist/editor-world.js.map +1 -1
  136. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +3 -0
  137. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
  138. package/node_modules/@fps-games/editor-babylon/dist/index.js +3 -0
  139. package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
  140. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts +52 -0
  141. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts.map +1 -0
  142. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +1395 -0
  143. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -0
  144. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts.map +1 -1
  145. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js +4 -65
  146. package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js.map +1 -1
  147. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts +28 -0
  148. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts.map +1 -0
  149. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js +235 -0
  150. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js.map +1 -0
  151. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts +37 -0
  152. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts.map +1 -0
  153. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js +451 -0
  154. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js.map +1 -0
  155. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.d.ts.map +1 -1
  156. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js +14 -3
  157. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js.map +1 -1
  158. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts +1 -0
  159. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts.map +1 -1
  160. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js +20 -4
  161. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js.map +1 -1
  162. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts +3 -6
  163. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts.map +1 -1
  164. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js +4 -37
  165. package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js.map +1 -1
  166. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +74 -1
  167. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  168. package/node_modules/@fps-games/editor-babylon/dist/projection.js +641 -52
  169. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  170. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts +11 -0
  171. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts.map +1 -1
  172. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +113 -29
  173. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js.map +1 -1
  174. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts +13 -1
  175. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts.map +1 -1
  176. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js +543 -3
  177. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js.map +1 -1
  178. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  179. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +8 -2
  180. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  181. package/node_modules/@fps-games/editor-browser/dist/index.js +4 -0
  182. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  183. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts +5 -0
  184. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -0
  185. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +23 -0
  186. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -0
  187. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js +1 -1
  188. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js.map +1 -1
  189. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
  190. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +76 -9
  191. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
  192. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +1 -1
  193. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +3 -2
  194. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -1
  195. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts +21 -0
  196. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts.map +1 -0
  197. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js +75 -0
  198. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js.map +1 -0
  199. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +2 -0
  200. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  201. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +326 -72
  202. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  203. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts +5 -0
  204. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts.map +1 -0
  205. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js +92 -0
  206. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js.map +1 -0
  207. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +4 -1
  208. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
  209. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +22 -7
  210. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +1 -1
  211. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts +4 -0
  212. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
  213. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +24 -11
  214. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
  215. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  216. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  217. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +7 -0
  218. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  219. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js +1 -1
  220. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js.map +1 -1
  221. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +4 -0
  222. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  223. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +1471 -29
  224. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  225. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +70 -0
  226. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -0
  227. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +171 -0
  228. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -0
  229. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts +1 -1
  230. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -1
  231. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js +2 -2
  232. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js.map +1 -1
  233. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -1
  234. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +9 -2
  235. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -1
  236. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +301 -3
  237. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  238. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +12 -1
  239. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
  240. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +13 -1
  241. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
  242. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +6 -4
  243. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  244. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +1501 -122
  245. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  246. package/node_modules/@fps-games/editor-browser/package.json +3 -3
  247. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts +18 -0
  248. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts.map +1 -0
  249. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js +102 -0
  250. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js.map +1 -0
  251. package/node_modules/@fps-games/editor-core/dist/index.d.ts +1 -0
  252. package/node_modules/@fps-games/editor-core/dist/index.d.ts.map +1 -1
  253. package/node_modules/@fps-games/editor-core/dist/index.js +1 -0
  254. package/node_modules/@fps-games/editor-core/dist/index.js.map +1 -1
  255. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +1 -1
  256. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -1
  257. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +3 -1
  258. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
  259. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +1 -0
  260. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
  261. package/node_modules/@fps-games/editor-core/package.json +2 -2
  262. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  263. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts +3 -0
  264. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts.map +1 -0
  265. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js +9 -0
  266. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js.map +1 -0
  267. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts +6 -0
  268. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts.map +1 -0
  269. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js +89 -0
  270. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js.map +1 -0
  271. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts +18 -0
  272. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts.map +1 -0
  273. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js +121 -0
  274. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js.map +1 -0
  275. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts +4 -0
  276. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts.map +1 -0
  277. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js +3 -0
  278. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js.map +1 -0
  279. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts +27 -0
  280. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts.map +1 -0
  281. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js +782 -0
  282. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js.map +1 -0
  283. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts +5 -0
  284. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts.map +1 -0
  285. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js +5 -0
  286. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js.map +1 -0
  287. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts +80 -0
  288. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts.map +1 -0
  289. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js +600 -0
  290. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js.map +1 -0
  291. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts +51 -0
  292. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts.map +1 -0
  293. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js +2 -0
  294. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js.map +1 -0
  295. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
  296. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +17 -3
  297. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
  298. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.d.ts.map +1 -1
  299. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js +2 -1
  300. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js.map +1 -1
  301. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts +3 -2
  302. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts.map +1 -1
  303. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts +1 -1
  304. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
  305. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +48 -20
  306. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
  307. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts +1 -1
  308. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts.map +1 -1
  309. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js +1 -1
  310. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js.map +1 -1
  311. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.d.ts.map +1 -1
  312. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js +2 -1
  313. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js.map +1 -1
  314. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts +3 -0
  315. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts.map +1 -1
  316. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +97 -2
  317. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
  318. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +1143 -8
  319. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
  320. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +145 -2
  321. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
  322. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts +1 -1
  323. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts.map +1 -1
  324. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js +1 -1
  325. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js.map +1 -1
  326. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
  327. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +24 -9
  328. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
  329. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts +6 -0
  330. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts.map +1 -1
  331. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js +31 -0
  332. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js.map +1 -1
  333. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +3 -0
  334. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  335. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +3 -0
  336. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  337. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts +82 -2
  338. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts.map +1 -1
  339. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js +396 -22
  340. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js.map +1 -1
  341. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts +1 -1
  342. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts.map +1 -1
  343. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js +1 -1
  344. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js.map +1 -1
  345. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.d.ts.map +1 -1
  346. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js +0 -3
  347. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js.map +1 -1
  348. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts +29 -1
  349. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts.map +1 -1
  350. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js +143 -0
  351. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js.map +1 -1
  352. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.d.ts.map +1 -1
  353. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js +3 -7
  354. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js.map +1 -1
  355. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.d.ts.map +1 -1
  356. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js +6 -0
  357. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js.map +1 -1
  358. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts +2 -10
  359. package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts.map +1 -1
  360. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
  361. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +107 -11
  362. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
  363. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.d.ts.map +1 -1
  364. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js +4 -1
  365. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js.map +1 -1
  366. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.d.ts.map +1 -1
  367. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js +19 -1
  368. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js.map +1 -1
  369. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.d.ts.map +1 -1
  370. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +19 -3
  371. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
  372. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts +1 -2
  373. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts.map +1 -1
  374. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js +0 -14
  375. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js.map +1 -1
  376. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts +1 -7
  377. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts.map +1 -1
  378. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js +3 -32
  379. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js.map +1 -1
  380. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
  381. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +82 -63
  382. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
  383. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +7 -23
  384. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
  385. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts +5 -0
  386. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts.map +1 -0
  387. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js +996 -0
  388. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js.map +1 -0
  389. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts +3 -0
  390. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts.map +1 -0
  391. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js +3 -0
  392. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js.map +1 -0
  393. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts +152 -0
  394. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts.map +1 -0
  395. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js +2 -0
  396. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js.map +1 -0
  397. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
  398. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +44 -2
  399. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
  400. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts +1 -0
  401. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
  402. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +244 -12
  403. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
  404. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
  405. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +216 -67
  406. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
  407. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.d.ts.map +1 -1
  408. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js +7 -4
  409. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js.map +1 -1
  410. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.d.ts.map +1 -1
  411. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js +45 -1
  412. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js.map +1 -1
  413. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.d.ts.map +1 -1
  414. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js +2 -1
  415. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js.map +1 -1
  416. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts +5 -0
  417. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts.map +1 -0
  418. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js +5 -0
  419. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js.map +1 -0
  420. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts +21 -0
  421. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts.map +1 -0
  422. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js +158 -0
  423. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js.map +1 -0
  424. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts +5 -0
  425. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts.map +1 -0
  426. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js +83 -0
  427. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js.map +1 -0
  428. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts +35 -0
  429. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts.map +1 -0
  430. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js +363 -0
  431. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js.map +1 -0
  432. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts +105 -0
  433. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts.map +1 -0
  434. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js +6 -0
  435. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js.map +1 -0
  436. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts +3 -0
  437. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts.map +1 -1
  438. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js +44 -0
  439. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js.map +1 -1
  440. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts +26 -0
  441. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts.map +1 -0
  442. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js +105 -0
  443. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js.map +1 -0
  444. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts +3 -0
  445. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts.map +1 -1
  446. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js +3 -0
  447. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js.map +1 -1
  448. package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
  449. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts +1127 -0
  450. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts.map +1 -0
  451. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js +2180 -0
  452. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js.map +1 -0
  453. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts +68 -0
  454. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts.map +1 -0
  455. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js +23 -0
  456. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js.map +1 -0
  457. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +57 -3
  458. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
  459. package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
  460. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +21 -0
  461. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
  462. package/node_modules/@fps-games/editor-protocol/dist/index.js +3 -0
  463. package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
  464. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts +128 -0
  465. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts.map +1 -0
  466. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js +2 -0
  467. package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js.map +1 -0
  468. package/node_modules/@fps-games/editor-protocol/package.json +1 -1
  469. package/package.json +8 -8
@@ -3,6 +3,7 @@ import { applyBabylonDefaultOutline } from '@fps-games/babylon-renderer';
3
3
  import { applyArtistMaterialProfileToRuntimeMaterial } from './material-property-adapter.js';
4
4
  import { pickBabylonProjectionNodeIdAt, resolveBabylonPickSelectionNodeId, resolveBabylonProjectionNodeId, } from './projection-pick-resolver.js';
5
5
  import { normalizeProjectionOwnerNodePath, readProjectionSourceNodeSegment, } from './projection-source-owner-path.js';
6
+ import { createMaterialSlotOwnerPathMatchKey, isMaterialSlotOwnerPathMatch, } from './material-slot-source-resolver.js';
6
7
  const LARGE_SELECTION_EDGE_LIMIT = 200;
7
8
  const PROJECTION_LOCAL_MATRIX_METADATA_KEY = 'editorLocalTransformMatrix';
8
9
  const ASSET_MESH_SELECTION_SEPARATOR = '::assetMesh::';
@@ -14,6 +15,9 @@ function requireBabylonCtor(value, name) {
14
15
  export function createBabylonEditorProjection(options) {
15
16
  const projections = new Map();
16
17
  const projectionParentIds = new Map();
18
+ const projectionAuthoredActive = new Map();
19
+ const previewVisibilityOverrides = new Map();
20
+ const shadowDebugOverlayObjects = [];
17
21
  const selectionEdgesPrewarm = options.selectionEdgesPrewarm ?? 'eager';
18
22
  const activeBatches = new Set();
19
23
  const idleWaiters = new Set();
@@ -114,6 +118,7 @@ export function createBabylonEditorProjection(options) {
114
118
  batch.settledNodeIds.add(node.id);
115
119
  if (projections.get(node.id) === projection && !projection.root.isDisposed?.()) {
116
120
  delete projection.loadPromise;
121
+ applyProjectionPreviewVisibility(node.id);
117
122
  applyProjectionOutline(node, projection);
118
123
  scheduleProjectionSelectionEdgesPrewarm(projection);
119
124
  options.onProjectionReady?.({ nodeId: node.id, async: true });
@@ -124,6 +129,7 @@ export function createBabylonEditorProjection(options) {
124
129
  const disposeProjectedNode = (projection) => {
125
130
  projection.selectionEdgesPrewarmCancel?.();
126
131
  projection.selectionEdgesPrewarmCancel = null;
132
+ projection.importStructure = null;
127
133
  for (const animationGroup of projection.animationGroups) {
128
134
  animationGroup.dispose?.();
129
135
  }
@@ -135,11 +141,42 @@ export function createBabylonEditorProjection(options) {
135
141
  const disposeAll = () => {
136
142
  markActiveBatchesStale();
137
143
  projectionGeneration += 1;
144
+ clearShadowDebugOverlayObjects();
138
145
  for (const projection of projections.values()) {
139
146
  disposeProjectedNode(projection);
140
147
  }
141
148
  projections.clear();
142
149
  projectionParentIds.clear();
150
+ projectionAuthoredActive.clear();
151
+ previewVisibilityOverrides.clear();
152
+ };
153
+ const createPreviewVisibilityEntry = (nodeId, visible) => {
154
+ const authoredActive = projectionAuthoredActive.get(nodeId) !== false;
155
+ return {
156
+ nodeId,
157
+ visible,
158
+ authoredActive,
159
+ effectiveVisible: authoredActive && visible !== false,
160
+ };
161
+ };
162
+ const applyProjectionPreviewVisibility = (nodeId) => {
163
+ const projection = projections.get(nodeId);
164
+ if (!projection)
165
+ return;
166
+ const authoredActive = projectionAuthoredActive.get(nodeId) !== false;
167
+ const override = previewVisibilityOverrides.get(nodeId);
168
+ const effectiveVisible = authoredActive && override !== false;
169
+ projection.root?.setEnabled?.(effectiveVisible);
170
+ for (const runtimeObject of projection.runtimeObjects) {
171
+ runtimeObject.setEnabled?.(effectiveVisible);
172
+ }
173
+ };
174
+ const clearShadowDebugOverlayObjects = () => {
175
+ const hadObjects = shadowDebugOverlayObjects.length > 0;
176
+ for (const object of shadowDebugOverlayObjects.splice(0)) {
177
+ object.dispose?.();
178
+ }
179
+ return hadObjects;
143
180
  };
144
181
  const scheduleProjectionSelectionEdgesPrewarm = (projection) => {
145
182
  projection.selectionEdgesPrewarmCancel?.();
@@ -177,7 +214,8 @@ export function createBabylonEditorProjection(options) {
177
214
  };
178
215
  projections.set(node.id, projection);
179
216
  projectionParentIds.set(node.id, node.parentId ?? null);
180
- root.setEnabled?.(node.active !== false);
217
+ projectionAuthoredActive.set(node.id, node.active !== false);
218
+ applyProjectionPreviewVisibility(node.id);
181
219
  if (node.transform)
182
220
  applyProjectionTransform(options.babylon, root, node.transform);
183
221
  if (node.helperKind !== 'root' && !attachRuntimeProjection(options.babylon, options.scene, node, projection)) {
@@ -212,6 +250,8 @@ export function createBabylonEditorProjection(options) {
212
250
  return;
213
251
  projections.delete(nodeId);
214
252
  projectionParentIds.delete(nodeId);
253
+ projectionAuthoredActive.delete(nodeId);
254
+ previewVisibilityOverrides.delete(nodeId);
215
255
  syncProjectionHierarchy();
216
256
  disposeProjectedNode(existing);
217
257
  };
@@ -262,6 +302,9 @@ export function createBabylonEditorProjection(options) {
262
302
  }
263
303
  return transforms;
264
304
  },
305
+ readNodeImportStructure(nodeId) {
306
+ return cloneProjectionImportStructureSnapshot(projections.get(nodeId)?.importStructure ?? null);
307
+ },
265
308
  setNodeTransformPreview(nodeId, transform) {
266
309
  const projection = projections.get(nodeId);
267
310
  if (!projection?.root)
@@ -303,15 +346,28 @@ export function createBabylonEditorProjection(options) {
303
346
  const projection = projections.get(node.id);
304
347
  if (!projection)
305
348
  return;
306
- projection.root?.setEnabled?.(node.active !== false);
307
- for (const runtimeObject of projection.runtimeObjects) {
308
- runtimeObject.setEnabled?.(node.active !== false);
309
- }
349
+ projectionAuthoredActive.set(node.id, node.active !== false);
350
+ applyProjectionPreviewVisibility(node.id);
351
+ projectionParentIds.set(node.id, node.parentId ?? null);
352
+ syncProjectionHierarchy();
353
+ if (node.transform)
354
+ applyProjectionTransform(options.babylon, projection.root, node.transform);
355
+ scheduleProjectionSelectionEdgesPrewarm(projection);
356
+ },
357
+ syncRuntimeNode(node) {
358
+ const projection = projections.get(node.id);
359
+ if (!projection || node.runtimeKind !== 'light')
360
+ return false;
361
+ projectionAuthoredActive.set(node.id, node.active !== false);
362
+ applyProjectionPreviewVisibility(node.id);
310
363
  projectionParentIds.set(node.id, node.parentId ?? null);
311
364
  syncProjectionHierarchy();
312
365
  if (node.transform)
313
366
  applyProjectionTransform(options.babylon, projection.root, node.transform);
367
+ if (!syncRuntimeLightProjection(options.babylon, options.scene, node, projection))
368
+ return false;
314
369
  scheduleProjectionSelectionEdgesPrewarm(projection);
370
+ return true;
315
371
  },
316
372
  syncNodeMetadata(node) {
317
373
  const projection = projections.get(node.id);
@@ -337,6 +393,55 @@ export function createBabylonEditorProjection(options) {
337
393
  getProjectedNode(nodeId) {
338
394
  return projections.get(nodeId) ?? null;
339
395
  },
396
+ getProjectedNodeIds() {
397
+ return [...projections.keys()];
398
+ },
399
+ getProjectionParentIds(nodeId) {
400
+ const parentIds = [];
401
+ const seen = new Set([nodeId]);
402
+ let currentId = nodeId;
403
+ while (currentId) {
404
+ const parentId = projectionParentIds.get(currentId) ?? null;
405
+ if (!parentId || parentId === currentId || seen.has(parentId))
406
+ break;
407
+ seen.add(parentId);
408
+ parentIds.push(parentId);
409
+ currentId = parentId;
410
+ }
411
+ return parentIds;
412
+ },
413
+ getPreviewVisibilityOverrides() {
414
+ return [...previewVisibilityOverrides.entries()]
415
+ .map(([nodeId, visible]) => createPreviewVisibilityEntry(nodeId, visible));
416
+ },
417
+ setPreviewVisibilityOverrides(overrides) {
418
+ for (const [nodeId, visible] of Object.entries(overrides)) {
419
+ if (!projections.has(nodeId))
420
+ continue;
421
+ previewVisibilityOverrides.set(nodeId, visible !== false);
422
+ applyProjectionPreviewVisibility(nodeId);
423
+ }
424
+ return this.getPreviewVisibilityOverrides();
425
+ },
426
+ clearPreviewVisibilityOverrides() {
427
+ const changedNodeIds = [...previewVisibilityOverrides.keys()];
428
+ previewVisibilityOverrides.clear();
429
+ for (const nodeId of changedNodeIds)
430
+ applyProjectionPreviewVisibility(nodeId);
431
+ return [];
432
+ },
433
+ setShadowDebugOverlay(items) {
434
+ clearShadowDebugOverlayObjects();
435
+ for (const item of items) {
436
+ const object = createShadowDebugOverlayObject(options.babylon, options.scene, item);
437
+ if (object)
438
+ shadowDebugOverlayObjects.push(object);
439
+ }
440
+ return items.map(item => item.id);
441
+ },
442
+ clearShadowDebugOverlay() {
443
+ return clearShadowDebugOverlayObjects();
444
+ },
340
445
  dispose() {
341
446
  disposeAll();
342
447
  },
@@ -349,6 +454,156 @@ function readVector3(value, fallback) {
349
454
  z: Number.isFinite(value?.z) ? Number(value.z) : fallback.z,
350
455
  };
351
456
  }
457
+ function createShadowDebugOverlayObject(babylon, scene, item) {
458
+ if (item.kind === 'light-direction')
459
+ return createShadowDebugDirectionOverlay(babylon, scene, item);
460
+ const bounds = item.bounds ?? createBoundsFromCenterSize(item.center, item.size);
461
+ if (!bounds)
462
+ return null;
463
+ const MeshBuilder = babylon.MeshBuilder;
464
+ const StandardMaterial = babylon.StandardMaterial;
465
+ if (!MeshBuilder?.CreateBox || !StandardMaterial)
466
+ return null;
467
+ const size = {
468
+ x: Math.max(Math.abs(bounds.size.x), 0.01),
469
+ y: Math.max(Math.abs(bounds.size.y), item.kind === 'footprint' ? 0.015 : 0.01),
470
+ z: Math.max(Math.abs(bounds.size.z), 0.01),
471
+ };
472
+ const mesh = MeshBuilder.CreateBox(`${item.id}.shadowDebugOverlay`, {
473
+ width: size.x,
474
+ height: size.y,
475
+ depth: size.z,
476
+ }, scene);
477
+ if (!mesh)
478
+ return null;
479
+ mesh.id = item.id;
480
+ mesh.name = item.id;
481
+ mesh.isPickable = false;
482
+ mesh.renderingGroupId = 3;
483
+ mesh.metadata = createShadowDebugOverlayMetadata();
484
+ mesh.position = createBabylonVector3(babylon, bounds.center);
485
+ const material = new StandardMaterial(`${item.id}.shadowDebugOverlay.material`, scene);
486
+ const color = readShadowDebugOverlayColor(babylon, item.kind);
487
+ if (color) {
488
+ material.diffuseColor = color;
489
+ material.emissiveColor = color;
490
+ }
491
+ material.alpha = item.kind === 'receiver-surface' ? 0.14 : item.kind === 'footprint' ? 0.32 : 0.5;
492
+ material.wireframe = item.kind !== 'footprint' && item.kind !== 'receiver-surface';
493
+ material.disableLighting = true;
494
+ mesh.material = material;
495
+ const disposeMaterial = material.dispose?.bind(material);
496
+ const disposeMesh = mesh.dispose?.bind(mesh);
497
+ mesh.dispose = (...args) => {
498
+ disposeMaterial?.();
499
+ return disposeMesh?.(...args);
500
+ };
501
+ return mesh;
502
+ }
503
+ function createShadowDebugDirectionOverlay(babylon, scene, item) {
504
+ const MeshBuilder = babylon.MeshBuilder;
505
+ if (!MeshBuilder?.CreateLineSystem)
506
+ return null;
507
+ const center = item.center ?? item.bounds?.center;
508
+ const direction = normalizeDebugVec3(item.direction ?? { x: -0.3, y: -1, z: -0.2 });
509
+ if (!center || !direction)
510
+ return null;
511
+ const length = Math.max(item.size?.x ?? item.bounds?.size.x ?? 2, item.size?.y ?? item.bounds?.size.y ?? 2, item.size?.z ?? item.bounds?.size.z ?? 2, 2);
512
+ const start = createBabylonVector3(babylon, {
513
+ x: center.x - direction.x * length * 0.5,
514
+ y: center.y - direction.y * length * 0.5,
515
+ z: center.z - direction.z * length * 0.5,
516
+ });
517
+ const end = createBabylonVector3(babylon, {
518
+ x: center.x + direction.x * length * 0.5,
519
+ y: center.y + direction.y * length * 0.5,
520
+ z: center.z + direction.z * length * 0.5,
521
+ });
522
+ const arrowLeft = createBabylonVector3(babylon, {
523
+ x: end.x - direction.x * length * 0.18 + direction.z * length * 0.08,
524
+ y: end.y - direction.y * length * 0.18,
525
+ z: end.z - direction.z * length * 0.18 - direction.x * length * 0.08,
526
+ });
527
+ const arrowRight = createBabylonVector3(babylon, {
528
+ x: end.x - direction.x * length * 0.18 - direction.z * length * 0.08,
529
+ y: end.y - direction.y * length * 0.18,
530
+ z: end.z - direction.z * length * 0.18 + direction.x * length * 0.08,
531
+ });
532
+ const line = MeshBuilder.CreateLineSystem(`${item.id}.shadowDebugOverlay`, {
533
+ lines: [
534
+ [start, end],
535
+ [end, arrowLeft],
536
+ [end, arrowRight],
537
+ ],
538
+ }, scene);
539
+ if (!line)
540
+ return null;
541
+ line.id = item.id;
542
+ line.name = item.id;
543
+ line.isPickable = false;
544
+ line.renderingGroupId = 3;
545
+ line.metadata = createShadowDebugOverlayMetadata();
546
+ const color = readShadowDebugOverlayColor(babylon, item.kind);
547
+ if (color)
548
+ line.color = color;
549
+ return line;
550
+ }
551
+ function createShadowDebugOverlayMetadata() {
552
+ return {
553
+ shadowDebugOverlayInternal: true,
554
+ disablePlanarShadow: true,
555
+ disableBlobShadow: true,
556
+ disableStaticProjectedShadow: true,
557
+ };
558
+ }
559
+ function createBoundsFromCenterSize(center, size) {
560
+ if (!center || !size)
561
+ return null;
562
+ return {
563
+ center,
564
+ size,
565
+ min: {
566
+ x: center.x - size.x / 2,
567
+ y: center.y - size.y / 2,
568
+ z: center.z - size.z / 2,
569
+ },
570
+ max: {
571
+ x: center.x + size.x / 2,
572
+ y: center.y + size.y / 2,
573
+ z: center.z + size.z / 2,
574
+ },
575
+ };
576
+ }
577
+ function createBabylonVector3(babylon, value) {
578
+ const Vector3 = babylon.Vector3;
579
+ return Vector3 ? new Vector3(value.x, value.y, value.z) : { x: value.x, y: value.y, z: value.z };
580
+ }
581
+ function normalizeDebugVec3(value) {
582
+ const length = Math.hypot(value.x, value.y, value.z);
583
+ if (!Number.isFinite(length) || length <= 0.0001)
584
+ return null;
585
+ return {
586
+ x: value.x / length,
587
+ y: value.y / length,
588
+ z: value.z / length,
589
+ };
590
+ }
591
+ function readShadowDebugOverlayColor(babylon, kind) {
592
+ const Color3 = babylon.Color3;
593
+ if (!Color3)
594
+ return null;
595
+ if (kind === 'caster-bounds')
596
+ return new Color3(1, 0.78, 0.1);
597
+ if (kind === 'receiver-bounds')
598
+ return new Color3(0.1, 0.75, 1);
599
+ if (kind === 'receiver-surface')
600
+ return new Color3(0.05, 0.55, 1);
601
+ if (kind === 'light-direction')
602
+ return new Color3(1, 0.95, 0.2);
603
+ if (kind === 'footprint')
604
+ return new Color3(0.1, 1, 0.42);
605
+ return new Color3(1, 0.25, 0.25);
606
+ }
352
607
  function addVec3(left, right) {
353
608
  return {
354
609
  x: left.x + right.x,
@@ -478,7 +733,7 @@ function createProjectionRoot(babylon, scene, node) {
478
733
  editorProjection: {
479
734
  nodeId: node.id,
480
735
  ...(node.runtimeKind ? { runtimeKind: node.runtimeKind } : {}),
481
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
736
+ ...createProjectionShadowMetadata(node),
482
737
  },
483
738
  };
484
739
  return root;
@@ -531,7 +786,7 @@ function attachImportedProjectionResult(options, node, asset, projection, result
531
786
  editorProjection: {
532
787
  nodeId: node.id,
533
788
  sourceId: asset.sourceId,
534
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
789
+ ...createProjectionShadowMetadata(node),
535
790
  },
536
791
  };
537
792
  applyAssetDefaultsTransform(babylon, modelRoot, asset.transform);
@@ -551,7 +806,7 @@ function attachImportedProjectionResult(options, node, asset, projection, result
551
806
  editorProjection: {
552
807
  nodeId: node.id,
553
808
  sourceId: asset.sourceId,
554
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
809
+ ...createProjectionShadowMetadata(node),
555
810
  },
556
811
  };
557
812
  }
@@ -570,7 +825,7 @@ function attachImportedProjectionResult(options, node, asset, projection, result
570
825
  ownerNodePath,
571
826
  ...(selectionKey !== ownerNodePath ? { slotSelectionKey: selectionKey } : {}),
572
827
  runtimeKind: 'assetMesh',
573
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
828
+ ...createProjectionShadowMetadata(node),
574
829
  },
575
830
  };
576
831
  }
@@ -581,12 +836,215 @@ function attachImportedProjectionResult(options, node, asset, projection, result
581
836
  }
582
837
  projection.animationGroups = result.animationGroups ?? [];
583
838
  projection.outlineMeshes = (result.meshes ?? []).filter((mesh) => mesh.getTotalVertices?.() > 0);
839
+ projection.importStructure = createProjectionImportStructureSnapshot(node, asset, modelRoot, result);
584
840
  }
585
841
  catch (error) {
586
842
  disposeImportedProjectionResult(result);
587
843
  throw error;
588
844
  }
589
845
  }
846
+ function createProjectionImportStructureSnapshot(node, asset, modelRoot, result) {
847
+ const runtimeNodes = collectProjectionImportRuntimeNodes(modelRoot, result);
848
+ const nodeIdByRuntimeNode = new Map();
849
+ const materialIdByRuntimeMaterial = new Map();
850
+ const textureIdByRuntimeTexture = new Map();
851
+ const materialNodeIds = new Map();
852
+ const materialTextureIds = new Map();
853
+ const rootSnapshotId = 'root';
854
+ const snapshots = [{
855
+ id: rootSnapshotId,
856
+ parentId: null,
857
+ name: readProjectionRuntimeName(modelRoot, node.name ?? node.id),
858
+ kind: 'root',
859
+ }];
860
+ for (const runtimeNode of runtimeNodes) {
861
+ const snapshotId = createProjectionImportRuntimeNodeId(runtimeNode, nodeIdByRuntimeNode.size);
862
+ nodeIdByRuntimeNode.set(runtimeNode, snapshotId);
863
+ }
864
+ for (const runtimeNode of runtimeNodes) {
865
+ const snapshotId = nodeIdByRuntimeNode.get(runtimeNode);
866
+ if (!snapshotId)
867
+ continue;
868
+ const materialIds = readProjectionRuntimeNodeMaterials(runtimeNode)
869
+ .map(runtimeMaterial => getProjectionImportMaterialSnapshotId(runtimeMaterial, materialIdByRuntimeMaterial))
870
+ .filter((materialId) => !!materialId);
871
+ for (const materialId of materialIds) {
872
+ const nodeIds = materialNodeIds.get(materialId) ?? new Set();
873
+ nodeIds.add(snapshotId);
874
+ materialNodeIds.set(materialId, nodeIds);
875
+ const textureIds = readProjectionRuntimeMaterialTextures(readProjectionRuntimeNodeMaterialById(runtimeNode, runtimeNode, materialId, materialIdByRuntimeMaterial))
876
+ .map(runtimeTexture => getProjectionImportTextureSnapshotId(runtimeTexture, textureIdByRuntimeTexture))
877
+ .filter((textureId) => !!textureId);
878
+ const materialTextures = materialTextureIds.get(materialId) ?? new Set();
879
+ for (const textureId of textureIds)
880
+ materialTextures.add(textureId);
881
+ materialTextureIds.set(materialId, materialTextures);
882
+ }
883
+ snapshots.push({
884
+ id: snapshotId,
885
+ parentId: resolveProjectionImportRuntimeParentId(runtimeNode, modelRoot, nodeIdByRuntimeNode, rootSnapshotId),
886
+ name: readProjectionRuntimeName(runtimeNode, snapshotId),
887
+ kind: isProjectionRuntimeMeshLike(runtimeNode) ? 'mesh' : 'transform',
888
+ ...readProjectionRuntimeSourceName(runtimeNode),
889
+ ...readProjectionRuntimeOwnerNodePath(runtimeNode),
890
+ ...(materialIds.length > 0 ? { materialIds } : {}),
891
+ });
892
+ }
893
+ const materials = [...materialIdByRuntimeMaterial.entries()].map(([runtimeMaterial, id]) => ({
894
+ id,
895
+ name: readProjectionRuntimeName(runtimeMaterial, id),
896
+ ...readProjectionRuntimeKind(runtimeMaterial),
897
+ nodeIds: [...(materialNodeIds.get(id) ?? [])],
898
+ textureIds: [...(materialTextureIds.get(id) ?? [])],
899
+ }));
900
+ const textures = [...textureIdByRuntimeTexture.entries()].map(([runtimeTexture, id]) => ({
901
+ id,
902
+ name: readProjectionRuntimeName(runtimeTexture, id),
903
+ ...readProjectionRuntimeKind(runtimeTexture),
904
+ ...readProjectionRuntimeTextureUrl(runtimeTexture),
905
+ }));
906
+ const animations = createProjectionImportAnimationSnapshots(result.animationGroups ?? []);
907
+ return {
908
+ projectionNodeId: node.id,
909
+ ...(asset.id ? { assetId: asset.id } : {}),
910
+ ...(asset.sourceId ? { sourceId: asset.sourceId } : {}),
911
+ nodes: snapshots,
912
+ materials,
913
+ textures,
914
+ animations,
915
+ };
916
+ }
917
+ function collectProjectionImportRuntimeNodes(modelRoot, result) {
918
+ const known = new Set([
919
+ ...(result.transformNodes ?? []),
920
+ ...(result.meshes ?? []),
921
+ ].filter(Boolean));
922
+ const ordered = [];
923
+ const visit = (runtimeNode) => {
924
+ for (const child of readProjectionRuntimeChildren(runtimeNode)) {
925
+ if (!known.has(child) || ordered.includes(child))
926
+ continue;
927
+ ordered.push(child);
928
+ visit(child);
929
+ }
930
+ };
931
+ visit(modelRoot);
932
+ for (const runtimeNode of known) {
933
+ if (!ordered.includes(runtimeNode))
934
+ ordered.push(runtimeNode);
935
+ }
936
+ return ordered;
937
+ }
938
+ function readProjectionRuntimeChildren(runtimeNode) {
939
+ const children = runtimeNode?.getChildren?.();
940
+ return Array.isArray(children) ? children : [];
941
+ }
942
+ function createProjectionImportRuntimeNodeId(runtimeNode, index) {
943
+ const sourceName = readProjectionSourceNodeSegment(runtimeNode);
944
+ const rawName = sourceName || runtimeNode?.name || runtimeNode?.id || `node-${index + 1}`;
945
+ return `${isProjectionRuntimeMeshLike(runtimeNode) ? 'mesh' : 'node'}:${sanitizeProjectionImportSnapshotId(rawName)}:${index + 1}`;
946
+ }
947
+ function resolveProjectionImportRuntimeParentId(runtimeNode, modelRoot, nodeIdByRuntimeNode, rootSnapshotId) {
948
+ const parent = runtimeNode?.parent ?? null;
949
+ if (!parent || parent === modelRoot)
950
+ return rootSnapshotId;
951
+ return nodeIdByRuntimeNode.get(parent) ?? rootSnapshotId;
952
+ }
953
+ function isProjectionRuntimeMeshLike(runtimeNode) {
954
+ return typeof runtimeNode?.getTotalVertices === 'function';
955
+ }
956
+ function readProjectionRuntimeNodeMaterials(runtimeNode) {
957
+ const material = runtimeNode?.material;
958
+ if (!material)
959
+ return [];
960
+ const subMaterials = material.subMaterials;
961
+ if (Array.isArray(subMaterials) && subMaterials.length > 0) {
962
+ return subMaterials.filter(Boolean);
963
+ }
964
+ return [material];
965
+ }
966
+ function readProjectionRuntimeNodeMaterialById(runtimeNode, _fallbackNode, materialId, materialIdByRuntimeMaterial) {
967
+ for (const material of readProjectionRuntimeNodeMaterials(runtimeNode)) {
968
+ if (materialIdByRuntimeMaterial.get(material) === materialId)
969
+ return material;
970
+ }
971
+ return null;
972
+ }
973
+ function getProjectionImportMaterialSnapshotId(runtimeMaterial, materialIdByRuntimeMaterial) {
974
+ if (!runtimeMaterial)
975
+ return null;
976
+ const existing = materialIdByRuntimeMaterial.get(runtimeMaterial);
977
+ if (existing)
978
+ return existing;
979
+ const id = `material:${sanitizeProjectionImportSnapshotId(readProjectionRuntimeName(runtimeMaterial, 'material'))}:${materialIdByRuntimeMaterial.size + 1}`;
980
+ materialIdByRuntimeMaterial.set(runtimeMaterial, id);
981
+ return id;
982
+ }
983
+ function readProjectionRuntimeMaterialTextures(runtimeMaterial) {
984
+ if (!runtimeMaterial)
985
+ return [];
986
+ const textures = runtimeMaterial.getActiveTextures?.();
987
+ return Array.isArray(textures) ? textures.filter(Boolean) : [];
988
+ }
989
+ function getProjectionImportTextureSnapshotId(runtimeTexture, textureIdByRuntimeTexture) {
990
+ if (!runtimeTexture)
991
+ return null;
992
+ const existing = textureIdByRuntimeTexture.get(runtimeTexture);
993
+ if (existing)
994
+ return existing;
995
+ const name = readProjectionRuntimeTextureUrl(runtimeTexture).url
996
+ ?? readProjectionRuntimeName(runtimeTexture, 'texture');
997
+ const id = `texture:${sanitizeProjectionImportSnapshotId(name)}:${textureIdByRuntimeTexture.size + 1}`;
998
+ textureIdByRuntimeTexture.set(runtimeTexture, id);
999
+ return id;
1000
+ }
1001
+ function createProjectionImportAnimationSnapshots(animationGroups) {
1002
+ return animationGroups.filter(Boolean).map((animationGroup, index) => ({
1003
+ id: `animation:${sanitizeProjectionImportSnapshotId(readProjectionRuntimeName(animationGroup, 'animation'))}:${index + 1}`,
1004
+ name: readProjectionRuntimeName(animationGroup, `Animation ${index + 1}`),
1005
+ }));
1006
+ }
1007
+ function readProjectionRuntimeName(runtimeObject, fallback) {
1008
+ const name = runtimeObject?.name ?? runtimeObject?.id;
1009
+ return typeof name === 'string' && name.trim() ? name.trim() : fallback;
1010
+ }
1011
+ function readProjectionRuntimeKind(runtimeObject) {
1012
+ const kind = runtimeObject?.getClassName?.();
1013
+ return typeof kind === 'string' && kind.trim() ? { kind: kind.trim() } : {};
1014
+ }
1015
+ function readProjectionRuntimeTextureUrl(runtimeTexture) {
1016
+ const url = runtimeTexture?.url ?? runtimeTexture?.name;
1017
+ return typeof url === 'string' && url.trim() ? { url: url.trim() } : {};
1018
+ }
1019
+ function readProjectionRuntimeSourceName(runtimeNode) {
1020
+ const sourceName = readProjectionSourceNodeSegment(runtimeNode);
1021
+ return sourceName ? { sourceName } : {};
1022
+ }
1023
+ function readProjectionRuntimeOwnerNodePath(runtimeNode) {
1024
+ const ownerNodePath = runtimeNode?.metadata?.editorProjection?.ownerNodePath;
1025
+ return typeof ownerNodePath === 'string' && ownerNodePath.trim() ? { ownerNodePath: ownerNodePath.trim() } : {};
1026
+ }
1027
+ function sanitizeProjectionImportSnapshotId(value) {
1028
+ return value.trim().toLowerCase().replace(/[^a-z0-9_.:-]+/gi, '-').replace(/^-+|-+$/g, '') || 'item';
1029
+ }
1030
+ function cloneProjectionImportStructureSnapshot(snapshot) {
1031
+ if (!snapshot)
1032
+ return null;
1033
+ return {
1034
+ ...snapshot,
1035
+ nodes: snapshot.nodes.map(item => ({
1036
+ ...item,
1037
+ ...(item.materialIds ? { materialIds: [...item.materialIds] } : {}),
1038
+ })),
1039
+ materials: snapshot.materials.map(item => ({
1040
+ ...item,
1041
+ nodeIds: [...item.nodeIds],
1042
+ textureIds: [...item.textureIds],
1043
+ })),
1044
+ textures: snapshot.textures.map(item => ({ ...item })),
1045
+ animations: snapshot.animations.map(item => ({ ...item })),
1046
+ };
1047
+ }
590
1048
  function disposeImportedProjectionResult(result) {
591
1049
  for (const animationGroup of result.animationGroups ?? []) {
592
1050
  animationGroup.dispose?.();
@@ -655,6 +1113,8 @@ function attachDirectionalLightProjection(babylon, scene, node, projection) {
655
1113
  light.setEnabled?.(node.active !== false);
656
1114
  projection.runtimeObjects.push(light);
657
1115
  }
1116
+ if (!settings.helperVisible)
1117
+ return;
658
1118
  const helper = MeshBuilder.CreateBox(`${node.id}.lightHelper`, {
659
1119
  size: 0.28,
660
1120
  }, scene);
@@ -755,14 +1215,14 @@ function createPrimitiveProjectionMesh(babylon, scene, node, options) {
755
1215
  mesh.metadata = createProjectionMetadata(node.id, {
756
1216
  runtimeKind: 'primitive',
757
1217
  primitiveShape: shape,
758
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
1218
+ ...createProjectionShadowMetadata(node),
759
1219
  });
760
1220
  return mesh;
761
1221
  }
762
1222
  function applyProjectionArtistMaterialProfilesToMeshes(options, node, modelRoot, meshes) {
763
- const slotProfiles = node.artistMaterialSlotProfiles ?? {};
1223
+ const slotBindings = createProjectionMaterialSlotBindings(node);
764
1224
  const hasRootProfile = !!node.artistMaterialProfile;
765
- const hasSlotProfiles = Object.keys(slotProfiles).length > 0;
1225
+ const hasSlotProfiles = slotBindings.length > 0;
766
1226
  if (!hasRootProfile && !hasSlotProfiles)
767
1227
  return [];
768
1228
  const clonedMaterials = [];
@@ -785,15 +1245,15 @@ function applyProjectionArtistMaterialProfilesToMeshes(options, node, modelRoot,
785
1245
  if (!material)
786
1246
  continue;
787
1247
  const ownerNodePath = buildProjectionOwnerNodePath(mesh, modelRoot, node.id);
788
- const slotProfile = resolveProjectionSlotProfile(slotProfiles, ownerNodePath, node.id);
789
- if (!slotProfile)
1248
+ const slotBinding = resolveProjectionSlotBinding(slotBindings, ownerNodePath, node.id);
1249
+ if (!slotBinding)
790
1250
  continue;
791
1251
  const slotMaterial = detachProjectionSlotMaterial(mesh, materialCounts, ownerNodePath);
792
1252
  if (!slotMaterial)
793
1253
  continue;
794
1254
  if (slotMaterial !== material)
795
1255
  clonedMaterials.push(slotMaterial);
796
- applyProjectionArtistMaterialProfile(options, slotMaterial, slotProfile);
1256
+ applyProjectionArtistMaterialProfile(options, slotMaterial, slotBinding.profile);
797
1257
  }
798
1258
  return clonedMaterials;
799
1259
  }
@@ -805,27 +1265,85 @@ function applyProjectionArtistMaterialProfile(options, material, profile) {
805
1265
  resolveTextureUrl: options.resolveTextureUrl,
806
1266
  });
807
1267
  }
808
- function resolveProjectionSlotProfile(slotProfiles, ownerNodePath, projectionNodeId) {
1268
+ function createProjectionMaterialSlotBindings(node) {
1269
+ const bindings = [];
1270
+ const occupiedOwnerPaths = new Set();
1271
+ for (const binding of node.artistMaterialSlotBindings ?? []) {
1272
+ const profile = binding?.profile;
1273
+ const slot = createProjectionMaterialSlotDescriptor(binding?.slot, node.id);
1274
+ if (!profile || !slot)
1275
+ continue;
1276
+ bindings.push({ slot, profile });
1277
+ occupiedOwnerPaths.add(slot.matchKey);
1278
+ }
1279
+ for (const [ownerNodePath, profile] of Object.entries(node.artistMaterialSlotProfiles ?? {})) {
1280
+ const slot = createProjectionMaterialSlotDescriptor({ ownerNodePath }, node.id);
1281
+ if (!profile || !slot || occupiedOwnerPaths.has(slot.matchKey))
1282
+ continue;
1283
+ bindings.push({ slot, profile });
1284
+ occupiedOwnerPaths.add(slot.matchKey);
1285
+ }
1286
+ return bindings;
1287
+ }
1288
+ function createProjectionMaterialSlotDescriptor(value, projectionNodeId) {
1289
+ if (!value || typeof value !== 'object')
1290
+ return null;
1291
+ const ownerNodePath = typeof value.ownerNodePath === 'string'
1292
+ ? normalizeProjectionOwnerNodePath(value.ownerNodePath, { projectionNodeId })
1293
+ : '';
1294
+ if (!ownerNodePath)
1295
+ return null;
1296
+ const slotId = typeof value.slotId === 'string' && value.slotId.trim() ? value.slotId.trim() : '';
1297
+ const label = typeof value.label === 'string' && value.label.trim() ? value.label.trim() : '';
1298
+ const nodeIndex = Number.isInteger(value.nodeIndex) ? value.nodeIndex : undefined;
1299
+ const nodeIndexPath = Array.isArray(value.nodeIndexPath)
1300
+ ? value.nodeIndexPath.filter((item) => Number.isInteger(item))
1301
+ : undefined;
1302
+ const meshIndex = Number.isInteger(value.meshIndex) ? value.meshIndex : undefined;
1303
+ const primitiveIndex = Number.isInteger(value.primitiveIndex) ? value.primitiveIndex : undefined;
1304
+ const sourceMaterialIndex = Number.isInteger(value.sourceMaterialIndex) ? value.sourceMaterialIndex : undefined;
1305
+ const sourceMaterialIndices = Array.isArray(value.sourceMaterialIndices)
1306
+ ? value.sourceMaterialIndices.filter((item) => Number.isInteger(item))
1307
+ : undefined;
1308
+ const materialName = typeof value.materialName === 'string' && value.materialName.trim() ? value.materialName.trim() : '';
1309
+ const materialNames = Array.isArray(value.materialNames)
1310
+ ? value.materialNames.filter((item) => typeof item === 'string' && !!item.trim()).map(item => item.trim())
1311
+ : undefined;
1312
+ return {
1313
+ ...(slotId ? { slotId } : {}),
1314
+ ownerNodePath,
1315
+ ...(label ? { label } : {}),
1316
+ ...(nodeIndex != null ? { nodeIndex } : {}),
1317
+ ...(nodeIndexPath && nodeIndexPath.length > 0 ? { nodeIndexPath } : {}),
1318
+ ...(meshIndex != null ? { meshIndex } : {}),
1319
+ ...(primitiveIndex != null ? { primitiveIndex } : {}),
1320
+ ...(sourceMaterialIndex != null ? { sourceMaterialIndex } : {}),
1321
+ ...(sourceMaterialIndices && sourceMaterialIndices.length > 0
1322
+ ? { sourceMaterialIndices }
1323
+ : {}),
1324
+ ...(materialName ? { materialName } : {}),
1325
+ ...(materialNames && materialNames.length > 0 ? { materialNames } : {}),
1326
+ key: slotId || ownerNodePath,
1327
+ normalizedOwnerNodePath: ownerNodePath,
1328
+ matchKey: createMaterialSlotOwnerPathMatchKey(ownerNodePath, { projectionNodeId }),
1329
+ };
1330
+ }
1331
+ function resolveProjectionSlotBinding(slotBindings, ownerNodePath, projectionNodeId) {
809
1332
  if (ownerNodePath == null)
810
1333
  return null;
811
- const direct = slotProfiles[ownerNodePath];
812
- if (direct)
813
- return direct;
814
1334
  const normalized = normalizeProjectionOwnerNodePath(ownerNodePath, { projectionNodeId });
815
- if (normalized !== ownerNodePath && slotProfiles[normalized])
816
- return slotProfiles[normalized];
1335
+ const normalizedMatchKey = createMaterialSlotOwnerPathMatchKey(normalized, { projectionNodeId });
817
1336
  let descendantMatch = null;
818
- for (const [candidatePath, profile] of Object.entries(slotProfiles)) {
819
- const normalizedCandidate = normalizeProjectionOwnerNodePath(candidatePath, { projectionNodeId });
820
- if (normalizedCandidate === normalized)
821
- return profile;
822
- if (isProjectionOwnerPathDescendant(normalized, normalizedCandidate)) {
823
- if (!descendantMatch || normalizedCandidate.length > descendantMatch.path.length) {
824
- descendantMatch = { path: normalizedCandidate, profile };
1337
+ for (const binding of slotBindings) {
1338
+ if (binding.slot.matchKey === normalizedMatchKey)
1339
+ return binding;
1340
+ if (isMaterialSlotOwnerPathMatch(normalized, binding.slot.normalizedOwnerNodePath, { projectionNodeId })) {
1341
+ if (!descendantMatch || binding.slot.matchKey.length > descendantMatch.slot.matchKey.length) {
1342
+ descendantMatch = binding;
825
1343
  }
826
1344
  }
827
1345
  }
828
- return descendantMatch?.profile ?? null;
1346
+ return descendantMatch;
829
1347
  }
830
1348
  function buildProjectionOwnerNodePath(node, rootNode, projectionNodeId) {
831
1349
  if (!node || !rootNode || node === rootNode)
@@ -857,11 +1375,6 @@ function stableProjectionNodeSegment(node) {
857
1375
  }
858
1376
  return null;
859
1377
  }
860
- function isProjectionOwnerPathDescendant(ownerNodePath, candidateAncestorPath) {
861
- if (!ownerNodePath || !candidateAncestorPath)
862
- return false;
863
- return ownerNodePath.startsWith(`${candidateAncestorPath}/`);
864
- }
865
1378
  function createAssetMeshProjectionNodeId(rootNodeId, ownerNodePath) {
866
1379
  return `${rootNodeId}${ASSET_MESH_SELECTION_SEPARATOR}${encodeURIComponent(ownerNodePath)}`;
867
1380
  }
@@ -869,9 +1382,9 @@ function resolveProjectionAssetMeshSelectionKey(asset, ownerNodePath, projection
869
1382
  const normalizedOwnerPath = normalizeProjectionOwnerNodePath(ownerNodePath, { projectionNodeId });
870
1383
  let bestSlot = null;
871
1384
  for (const slot of readProjectionAssetMaterialSlots(asset, projectionNodeId)) {
872
- if (!isProjectionOwnerPathSlotMatch(normalizedOwnerPath, slot.path))
1385
+ if (!isMaterialSlotOwnerPathMatch(normalizedOwnerPath, slot.normalizedOwnerNodePath, { projectionNodeId }))
873
1386
  continue;
874
- if (!bestSlot || slot.path.length > bestSlot.path.length) {
1387
+ if (!bestSlot || slot.matchKey.length > bestSlot.matchKey.length) {
875
1388
  bestSlot = slot;
876
1389
  }
877
1390
  }
@@ -891,8 +1404,7 @@ function readProjectionAssetMaterialSlots(asset, projectionNodeId) {
891
1404
  }
892
1405
  function readProjectionAssetMaterialSlot(value, projectionNodeId) {
893
1406
  if (typeof value === 'string') {
894
- const path = normalizeProjectionOwnerNodePath(value, { projectionNodeId });
895
- return path ? { key: path, path } : null;
1407
+ return createProjectionMaterialSlotDescriptor({ ownerNodePath: value }, projectionNodeId);
896
1408
  }
897
1409
  if (!value || typeof value !== 'object' || Array.isArray(value))
898
1410
  return null;
@@ -900,23 +1412,11 @@ function readProjectionAssetMaterialSlot(value, projectionNodeId) {
900
1412
  const rawOwnerPath = readProjectionAssetMaterialSlotString(record.ownerNodePath)
901
1413
  || readProjectionAssetMaterialSlotString(record.path)
902
1414
  || readProjectionAssetMaterialSlotString(record.name);
903
- const path = normalizeProjectionOwnerNodePath(rawOwnerPath, { projectionNodeId });
904
- if (!path)
905
- return null;
906
- const slotId = readProjectionAssetMaterialSlotString(record.slotId);
907
- return {
908
- key: slotId || path,
909
- path,
910
- };
1415
+ return createProjectionMaterialSlotDescriptor({ ...record, ownerNodePath: rawOwnerPath }, projectionNodeId);
911
1416
  }
912
1417
  function readProjectionAssetMaterialSlotString(value) {
913
1418
  return typeof value === 'string' ? value.trim() : '';
914
1419
  }
915
- function isProjectionOwnerPathSlotMatch(ownerNodePath, slotOwnerPath) {
916
- if (!ownerNodePath || !slotOwnerPath)
917
- return false;
918
- return ownerNodePath === slotOwnerPath || isProjectionOwnerPathDescendant(ownerNodePath, slotOwnerPath);
919
- }
920
1420
  function countProjectionMeshMaterials(meshes) {
921
1421
  const counts = new Map();
922
1422
  for (const mesh of meshes) {
@@ -992,7 +1492,7 @@ function createFallbackProjectionMesh(babylon, scene, node, rendererFallback) {
992
1492
  editorProjection: {
993
1493
  nodeId: node.id,
994
1494
  fallback: true,
995
- ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
1495
+ ...createProjectionShadowMetadata(node),
996
1496
  },
997
1497
  };
998
1498
  return mesh;
@@ -1112,6 +1612,8 @@ function attachHemisphericLightProjection(babylon, scene, node, projection) {
1112
1612
  light.setEnabled?.(node.active !== false);
1113
1613
  projection.runtimeObjects.push(light);
1114
1614
  }
1615
+ if (!settings.helperVisible)
1616
+ return;
1115
1617
  const helper = MeshBuilder.CreateSphere?.(`${node.id}.hemisphericLightHelper`, {
1116
1618
  diameter: 0.32,
1117
1619
  segments: 18,
@@ -1134,6 +1636,76 @@ function attachHemisphericLightProjection(babylon, scene, node, projection) {
1134
1636
  projection.runtimeObjects.push(material);
1135
1637
  projection.outlineMeshes = [helper];
1136
1638
  }
1639
+ function syncRuntimeLightProjection(babylon, scene, node, projection) {
1640
+ if (node.light?.type === 'hemispheric') {
1641
+ return syncRuntimeHemisphericLightProjection(babylon, scene, node, projection);
1642
+ }
1643
+ return syncRuntimeDirectionalLightProjection(babylon, scene, node, projection);
1644
+ }
1645
+ function syncRuntimeDirectionalLightProjection(babylon, scene, node, projection) {
1646
+ const settings = readProjectionDirectionalLightSettings(node.light?.type === 'directional' ? node.light : undefined);
1647
+ const light = findProjectionRuntimeLight(projection, node.id, 'directional');
1648
+ if (!light)
1649
+ return false;
1650
+ const hasHelper = !!scene.getMeshByName?.(`${node.id}.lightHelper`);
1651
+ if (settings.helperVisible !== hasHelper)
1652
+ return false;
1653
+ const Vector3 = requireBabylonCtor(babylon.Vector3, 'Vector3');
1654
+ const Color3 = requireBabylonCtor(babylon.Color3, 'Color3');
1655
+ copyOrAssignBabylonVec3(light, 'direction', new Vector3(settings.direction.x, settings.direction.y, settings.direction.z));
1656
+ light.intensity = settings.intensity;
1657
+ copyOrAssignBabylonColor(light, 'diffuse', new Color3(settings.diffuseColor?.r ?? 1, settings.diffuseColor?.g ?? 1, settings.diffuseColor?.b ?? 1));
1658
+ light.setEnabled?.(node.active !== false);
1659
+ if (settings.helperVisible)
1660
+ refreshLightDirectionLines(babylon, scene, node, projection, settings.direction);
1661
+ return true;
1662
+ }
1663
+ function syncRuntimeHemisphericLightProjection(babylon, scene, node, projection) {
1664
+ const settings = readProjectionHemisphericLightSettings(node.light?.type === 'hemispheric' ? node.light : undefined);
1665
+ const light = findProjectionRuntimeLight(projection, node.id, 'hemispheric');
1666
+ if (!light)
1667
+ return false;
1668
+ const hasHelper = !!scene.getMeshByName?.(`${node.id}.hemisphericLightHelper`);
1669
+ if (settings.helperVisible !== hasHelper)
1670
+ return false;
1671
+ const Color3 = requireBabylonCtor(babylon.Color3, 'Color3');
1672
+ light.intensity = settings.intensity;
1673
+ copyOrAssignBabylonColor(light, 'diffuse', new Color3(settings.diffuseColor?.r ?? 1, settings.diffuseColor?.g ?? 1, settings.diffuseColor?.b ?? 1));
1674
+ copyOrAssignBabylonColor(light, 'groundColor', new Color3(settings.groundColor?.r ?? 0.48, settings.groundColor?.g ?? 0.52, settings.groundColor?.b ?? 0.62));
1675
+ light.setEnabled?.(node.active !== false);
1676
+ return true;
1677
+ }
1678
+ function findProjectionRuntimeLight(projection, nodeId, lightType) {
1679
+ return projection.runtimeObjects.find(runtimeObject => {
1680
+ const metadata = runtimeObject?.metadata?.editorProjection;
1681
+ return metadata?.nodeId === nodeId
1682
+ && metadata?.runtimeKind === 'light'
1683
+ && metadata?.lightType === lightType;
1684
+ }) ?? null;
1685
+ }
1686
+ function refreshLightDirectionLines(babylon, scene, node, projection, direction) {
1687
+ const existing = scene.getMeshByName?.(`${node.id}.lightDirection`);
1688
+ existing?.dispose?.();
1689
+ const arrow = createLightDirectionLines(babylon, scene, node, direction);
1690
+ if (!arrow)
1691
+ return;
1692
+ arrow.parent = projection.root;
1693
+ arrow.isPickable = false;
1694
+ }
1695
+ function copyOrAssignBabylonVec3(target, key, value) {
1696
+ if (target?.[key]?.copyFrom) {
1697
+ target[key].copyFrom(value);
1698
+ return;
1699
+ }
1700
+ target[key] = value;
1701
+ }
1702
+ function copyOrAssignBabylonColor(target, key, value) {
1703
+ if (target?.[key]?.copyFrom) {
1704
+ target[key].copyFrom(value);
1705
+ return;
1706
+ }
1707
+ target[key] = value;
1708
+ }
1137
1709
  export function normalizeBabylonEditorProjectionCameraSettings(settings) {
1138
1710
  const targetOffset = readOptionalProjectionVec3(settings?.targetOffset);
1139
1711
  const targetScreenOffset = readOptionalProjectionVec2(settings?.targetScreenOffset);
@@ -1258,6 +1830,7 @@ function readProjectionDirectionalLightSettings(settings) {
1258
1830
  intensity: Math.max(0, readFiniteNumber(settings?.intensity, 2)),
1259
1831
  direction: readVector3(settings?.direction, { x: -0.3, y: -1, z: -0.2 }),
1260
1832
  diffuseColor: readProjectionColor(settings?.diffuseColor, { r: 1, g: 1, b: 1 }),
1833
+ helperVisible: settings?.helperVisible !== false,
1261
1834
  };
1262
1835
  }
1263
1836
  function readProjectionHemisphericLightSettings(settings) {
@@ -1266,6 +1839,7 @@ function readProjectionHemisphericLightSettings(settings) {
1266
1839
  intensity: Math.max(0, readFiniteNumber(settings?.intensity, 0.8)),
1267
1840
  diffuseColor: readProjectionColor(settings?.diffuseColor, { r: 1, g: 1, b: 1 }),
1268
1841
  groundColor: readProjectionColor(settings?.groundColor, { r: 0.48, g: 0.52, b: 0.62 }),
1842
+ helperVisible: settings?.helperVisible !== false,
1269
1843
  };
1270
1844
  }
1271
1845
  function readProjectionColor(value, fallback) {
@@ -1304,6 +1878,13 @@ function createProjectionMetadata(nodeId, extra = {}) {
1304
1878
  },
1305
1879
  };
1306
1880
  }
1881
+ function createProjectionShadowMetadata(node) {
1882
+ return {
1883
+ ...(node.shadowMode ? { shadowMode: node.shadowMode } : {}),
1884
+ ...(node.shadow ? { shadow: structuredClone(node.shadow) } : {}),
1885
+ ...(node.shadowPlan ? { shadowPlan: structuredClone(node.shadowPlan) } : {}),
1886
+ };
1887
+ }
1307
1888
  function syncProjectionNodeMetadata(projection, node) {
1308
1889
  walkProjectionRuntimeNodes(projection.root, (runtimeNode) => {
1309
1890
  syncProjectionRuntimeNodeMetadata(runtimeNode, node);
@@ -1332,6 +1913,14 @@ function syncProjectionRuntimeNodeMetadata(runtimeNode, node) {
1332
1913
  nextEditorProjection.shadowMode = node.shadowMode;
1333
1914
  else
1334
1915
  delete nextEditorProjection.shadowMode;
1916
+ if (node.shadow)
1917
+ nextEditorProjection.shadow = structuredClone(node.shadow);
1918
+ else
1919
+ delete nextEditorProjection.shadow;
1920
+ if (node.shadowPlan)
1921
+ nextEditorProjection.shadowPlan = structuredClone(node.shadowPlan);
1922
+ else
1923
+ delete nextEditorProjection.shadowPlan;
1335
1924
  runtimeNode.metadata = {
1336
1925
  ...(metadata ?? {}),
1337
1926
  editorProjection: nextEditorProjection,