@fps-games/editor 0.1.6-beta.1 → 0.1.7-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 (373) 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/index.d.ts +1 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/local-editor-agent-bridge-transport.d.ts +95 -0
  70. package/dist/local-editor-agent-bridge-transport.d.ts.map +1 -0
  71. package/dist/local-editor-agent-bridge-transport.js +340 -0
  72. package/dist/local-editor-agent-bridge-transport.js.map +1 -0
  73. package/dist/local-editor-agent-bridge.d.ts +2 -0
  74. package/dist/local-editor-agent-bridge.d.ts.map +1 -0
  75. package/dist/local-editor-agent-bridge.js +2 -0
  76. package/dist/local-editor-agent-bridge.js.map +1 -0
  77. package/dist/local-editor-harness.d.ts +26 -2
  78. package/dist/local-editor-harness.d.ts.map +1 -1
  79. package/dist/local-editor-harness.js +773 -75
  80. package/dist/local-editor-harness.js.map +1 -1
  81. package/dist/playable-babylon-rendering.js +20 -0
  82. package/dist/playable-babylon-rendering.js.map +1 -1
  83. package/dist/playable-local-editor-host.d.ts +5 -0
  84. package/dist/playable-local-editor-host.d.ts.map +1 -1
  85. package/dist/playable-local-editor-host.js +2 -0
  86. package/dist/playable-local-editor-host.js.map +1 -1
  87. package/dist/playable-sdk.d.ts +1 -1
  88. package/dist/playable-sdk.d.ts.map +1 -1
  89. package/dist/playable-sdk.js.map +1 -1
  90. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.d.ts.map +1 -1
  91. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js +6 -4
  92. package/node_modules/@fps-games/babylon-renderer/dist/shadows/blob-shadow-system.js.map +1 -1
  93. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.d.ts.map +1 -1
  94. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js +103 -1
  95. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-shaders.js.map +1 -1
  96. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.d.ts.map +1 -1
  97. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js +330 -27
  98. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js.map +1 -1
  99. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.d.ts.map +1 -1
  100. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js +159 -0
  101. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js.map +1 -1
  102. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js +8 -1
  103. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js.map +1 -1
  104. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts +53 -2
  105. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts.map +1 -1
  106. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js +1 -0
  107. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js.map +1 -1
  108. package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
  109. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +30 -0
  110. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  111. package/node_modules/@fps-games/editor-babylon/dist/projection.js +346 -11
  112. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  113. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts +11 -0
  114. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts.map +1 -1
  115. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +113 -29
  116. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js.map +1 -1
  117. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts +13 -1
  118. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts.map +1 -1
  119. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js +543 -3
  120. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js.map +1 -1
  121. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  122. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +5 -2
  123. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  124. package/node_modules/@fps-games/editor-browser/dist/index.js +3 -1
  125. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  126. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js +1 -1
  127. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js.map +1 -1
  128. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
  129. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +7 -9
  130. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
  131. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +2 -2
  132. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -1
  133. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts +21 -0
  134. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts.map +1 -0
  135. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js +75 -0
  136. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js.map +1 -0
  137. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  138. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +288 -71
  139. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  140. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts +5 -0
  141. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts.map +1 -0
  142. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js +92 -0
  143. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js.map +1 -0
  144. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +3 -0
  145. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
  146. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +22 -7
  147. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +1 -1
  148. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts +4 -0
  149. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
  150. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +21 -14
  151. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
  152. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  153. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +6 -4
  154. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  155. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +19 -1
  156. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -1
  157. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +79 -39
  158. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -1
  159. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js +2 -2
  160. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js.map +1 -1
  161. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +68 -1
  162. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  163. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +2 -0
  164. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
  165. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +10 -0
  166. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
  167. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +3 -2
  168. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  169. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +401 -241
  170. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  171. package/node_modules/@fps-games/editor-browser/dist/runtime-camera-debug-panel.d.ts +1 -0
  172. package/node_modules/@fps-games/editor-browser/dist/runtime-camera-debug-panel.d.ts.map +1 -1
  173. package/node_modules/@fps-games/editor-browser/dist/runtime-camera-debug-panel.js +1 -0
  174. package/node_modules/@fps-games/editor-browser/dist/runtime-camera-debug-panel.js.map +1 -1
  175. package/node_modules/@fps-games/editor-browser/dist/runtime-debug-panel-shell.d.ts +2 -0
  176. package/node_modules/@fps-games/editor-browser/dist/runtime-debug-panel-shell.d.ts.map +1 -1
  177. package/node_modules/@fps-games/editor-browser/dist/runtime-debug-panel-shell.js +27 -13
  178. package/node_modules/@fps-games/editor-browser/dist/runtime-debug-panel-shell.js.map +1 -1
  179. package/node_modules/@fps-games/editor-browser/dist/runtime-lighting-debug-panel.d.ts +1 -0
  180. package/node_modules/@fps-games/editor-browser/dist/runtime-lighting-debug-panel.d.ts.map +1 -1
  181. package/node_modules/@fps-games/editor-browser/dist/runtime-lighting-debug-panel.js +1 -0
  182. package/node_modules/@fps-games/editor-browser/dist/runtime-lighting-debug-panel.js.map +1 -1
  183. package/node_modules/@fps-games/editor-browser/package.json +3 -3
  184. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts +18 -0
  185. package/node_modules/@fps-games/editor-core/dist/agent-bridge.d.ts.map +1 -0
  186. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js +102 -0
  187. package/node_modules/@fps-games/editor-core/dist/agent-bridge.js.map +1 -0
  188. package/node_modules/@fps-games/editor-core/dist/index.d.ts +1 -0
  189. package/node_modules/@fps-games/editor-core/dist/index.d.ts.map +1 -1
  190. package/node_modules/@fps-games/editor-core/dist/index.js +1 -0
  191. package/node_modules/@fps-games/editor-core/dist/index.js.map +1 -1
  192. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +1 -1
  193. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
  194. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
  195. package/node_modules/@fps-games/editor-core/package.json +2 -2
  196. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  197. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts +3 -0
  198. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.d.ts.map +1 -0
  199. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js +9 -0
  200. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/config.js.map +1 -0
  201. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts +6 -0
  202. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts.map +1 -0
  203. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js +89 -0
  204. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js.map +1 -0
  205. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts +18 -0
  206. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.d.ts.map +1 -0
  207. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js +121 -0
  208. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/identity.js.map +1 -0
  209. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts +4 -0
  210. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts.map +1 -0
  211. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js +3 -0
  212. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js.map +1 -0
  213. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts +27 -0
  214. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.d.ts.map +1 -0
  215. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js +782 -0
  216. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js.map +1 -0
  217. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts +5 -0
  218. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts.map +1 -0
  219. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js +5 -0
  220. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js.map +1 -0
  221. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts +80 -0
  222. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts.map +1 -0
  223. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js +600 -0
  224. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js.map +1 -0
  225. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts +51 -0
  226. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.d.ts.map +1 -0
  227. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js +2 -0
  228. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/types.js.map +1 -0
  229. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts +0 -1
  230. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
  231. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +4 -42
  232. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
  233. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts +1 -1
  234. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts.map +1 -1
  235. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js +1 -1
  236. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js.map +1 -1
  237. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.d.ts.map +1 -1
  238. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js +2 -1
  239. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js.map +1 -1
  240. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts +3 -0
  241. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/types.d.ts.map +1 -1
  242. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +42 -2
  243. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
  244. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +612 -8
  245. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
  246. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +42 -0
  247. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
  248. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts +1 -1
  249. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts.map +1 -1
  250. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js +1 -1
  251. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js.map +1 -1
  252. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
  253. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +16 -9
  254. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
  255. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts +5 -0
  256. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts.map +1 -1
  257. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js +28 -0
  258. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js.map +1 -1
  259. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +3 -0
  260. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  261. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +3 -0
  262. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  263. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts +82 -2
  264. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts.map +1 -1
  265. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js +396 -22
  266. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js.map +1 -1
  267. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts +1 -1
  268. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts.map +1 -1
  269. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js +1 -1
  270. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js.map +1 -1
  271. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.d.ts.map +1 -1
  272. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js +0 -3
  273. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/validation.js.map +1 -1
  274. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts +29 -1
  275. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.d.ts.map +1 -1
  276. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js +143 -0
  277. package/node_modules/@fps-games/editor-playable-sdk/dist/lighting-debug/math.js.map +1 -1
  278. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
  279. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +99 -11
  280. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
  281. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.d.ts.map +1 -1
  282. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js +4 -1
  283. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js.map +1 -1
  284. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.d.ts.map +1 -1
  285. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js +19 -1
  286. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/transform.js.map +1 -1
  287. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.d.ts.map +1 -1
  288. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +19 -3
  289. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
  290. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts +1 -2
  291. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.d.ts.map +1 -1
  292. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js +0 -14
  293. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js.map +1 -1
  294. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts +1 -7
  295. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.d.ts.map +1 -1
  296. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js +3 -32
  297. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/import-plan.js.map +1 -1
  298. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
  299. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +16 -32
  300. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
  301. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +5 -22
  302. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
  303. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts +5 -0
  304. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts.map +1 -0
  305. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js +996 -0
  306. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js.map +1 -0
  307. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts +3 -0
  308. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts.map +1 -0
  309. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js +3 -0
  310. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js.map +1 -0
  311. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts +152 -0
  312. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts.map +1 -0
  313. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js +2 -0
  314. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js.map +1 -0
  315. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
  316. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +4 -0
  317. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
  318. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
  319. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +224 -12
  320. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
  321. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
  322. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +158 -50
  323. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
  324. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.d.ts.map +1 -1
  325. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js +45 -1
  326. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/patch.js.map +1 -1
  327. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts +5 -0
  328. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.d.ts.map +1 -0
  329. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js +5 -0
  330. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/index.js.map +1 -0
  331. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts +21 -0
  332. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.d.ts.map +1 -0
  333. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js +158 -0
  334. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/legacy.js.map +1 -0
  335. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts +5 -0
  336. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.d.ts.map +1 -0
  337. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js +83 -0
  338. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/quality.js.map +1 -0
  339. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts +35 -0
  340. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.d.ts.map +1 -0
  341. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js +363 -0
  342. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/resolver.js.map +1 -0
  343. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts +105 -0
  344. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.d.ts.map +1 -0
  345. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js +6 -0
  346. package/node_modules/@fps-games/editor-playable-sdk/dist/shadow-system/types.js.map +1 -0
  347. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts +3 -0
  348. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts.map +1 -1
  349. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js +44 -0
  350. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js.map +1 -1
  351. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts +26 -0
  352. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.d.ts.map +1 -0
  353. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js +105 -0
  354. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/asset-authoring.js.map +1 -0
  355. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts +3 -0
  356. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts.map +1 -1
  357. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js +3 -0
  358. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js.map +1 -1
  359. package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
  360. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts +1127 -0
  361. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts.map +1 -0
  362. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js +2180 -0
  363. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js.map +1 -0
  364. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts +68 -0
  365. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.d.ts.map +1 -0
  366. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js +23 -0
  367. package/node_modules/@fps-games/editor-protocol/dist/agent-trace.js.map +1 -0
  368. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +2 -0
  369. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
  370. package/node_modules/@fps-games/editor-protocol/dist/index.js +2 -0
  371. package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
  372. package/node_modules/@fps-games/editor-protocol/package.json +1 -1
  373. package/package.json +8 -8
@@ -11,7 +11,7 @@ export { createLocalEditorHierarchyBlankMenu, createLocalEditorHierarchyCopyShor
11
11
  export { createLocalEditorHierarchyController, resolveLocalEditorHierarchyCreateMarkerParentId, } from './local-editor-ui-hierarchy-controller.js';
12
12
  export { resolveLocalEditorHierarchySearchRows, } from './local-editor-ui-hierarchy-view.js';
13
13
  export { createLocalEditorHierarchyAttachDialog, resolveLocalEditorHierarchyAttachTargets, } from './local-editor-ui-hierarchy-attach-dialog.js';
14
- export { canLocalEditorHierarchyNodeHaveChildren, createLocalEditorHierarchyTreeModel, isLocalEditorHierarchyNodeSelectable, isLocalEditorHierarchyNodeMovable, } from './local-editor-ui-hierarchy-tree.js';
14
+ export { canLocalEditorHierarchyNodeHaveChildren, canLocalEditorHierarchyNodeDelete, canLocalEditorHierarchyNodeRename, canLocalEditorHierarchyNodeToggleEnabled, createLocalEditorHierarchyTreeModel, isLocalEditorHierarchyNodeSelectable, isLocalEditorHierarchyNodeMovable, } from './local-editor-ui-hierarchy-tree.js';
15
15
  export { createLocalEditorContextMenuController, } from './local-editor-ui-context-menu.js';
16
16
  export { createLocalEditorTooltipController, } from './local-editor-ui-tooltip.js';
17
17
  import { createLocalEditorWorkbenchInputRouter } from './local-editor-ui-input-router.js';
@@ -23,7 +23,7 @@ import { applyLocalEditorTheme, ensureLocalEditorTheme, LOCAL_EDITOR_THEME_CLASS
23
23
  import { createDefaultLocalEditorWorkbenchLayout, createLocalEditorWorkbenchLayoutController, createLocalEditorWorkbench, createSceneHeaderToolbar, createWorkbenchPanelContent, } from './local-editor-ui-workbench.js';
24
24
  import { createLocalEditorIcon, isLocalEditorIconName } from './local-editor-ui-icons.js';
25
25
  import { resolveLocalEditorBrowserAssetKind, } from './local-editor-ui-asset-kind.js';
26
- import { createLocalEditorPrefabStageTitle, filterLocalEditorPrefabStageStructureItems, findLocalEditorPrefabStageStructureItem, formatLocalEditorPrefabStageComparisonPreviewStatus, LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX, resolveLocalEditorRightDockVisibility, resolveLocalEditorPrefabStageComparisonPreviewTone, shouldLocalEditorClosePerformanceMonitor, shouldLocalEditorPrefabStageBlockHierarchyShortcut, shouldShowLocalEditorPrefabComparisonColumn, shouldToggleLocalEditorPrefabComparisonShortcut, } from './local-editor-ui-prefab-stage.js';
26
+ import { createLocalEditorPrefabStageTitle, findLocalEditorPrefabStageStructureItem, formatLocalEditorPrefabStageComparisonPreviewStatus, LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX, resolveLocalEditorRightDockVisibility, resolveLocalEditorPrefabStageComparisonPreviewTone, resolveLocalEditorPrefabStageWorkbenchLayout, resolveLocalEditorPreviewToolSupport, shouldLocalEditorClosePerformanceMonitor, shouldLocalEditorPrefabStageBlockHierarchyShortcut, shouldShowLocalEditorPrefabComparisonColumn, shouldToggleLocalEditorPrefabComparisonShortcut, } from './local-editor-ui-prefab-stage.js';
27
27
  export { applyLocalEditorBrowserInspectorControlBinding, createLocalEditorBrowserInspectorControlRegistry, formatLocalEditorBrowserInspectorNumberValue, formatLocalEditorBrowserInspectorValue, parseLocalEditorBrowserInspectorNumberValue, resolveLocalEditorBrowserInspectorSectionStatus, resolveLocalEditorBrowserInspectorControlRegistration, } from './local-editor-ui-panels.js';
28
28
  export { createLocalEditorBrowserInspectorGroupValueClipboardPayload, createLocalEditorBrowserInspectorVectorCopyPayload, parseLocalEditorBrowserInspectorGroupValueClipboardPayload, } from './local-editor-inspector-clipboard.js';
29
29
  export { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, isLocalEditorBrowserInspectorTransformVectorGroupPath, resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromProperties, } from './local-editor-inspector-groups.js';
@@ -109,14 +109,24 @@ const PLACEMENT_MODE_DESCRIPTIONS = {
109
109
  const VIEW_PRESET_ICONS = {
110
110
  perspective: 'view-perspective',
111
111
  top: 'view-top',
112
+ bottom: 'view-top',
112
113
  front: 'view-front',
114
+ back: 'view-front',
115
+ left: 'view-right',
113
116
  right: 'view-right',
117
+ iso: 'view-perspective',
118
+ threeQuarterTop: 'view-perspective',
114
119
  };
115
120
  const VIEW_PRESET_TOOLTIPS = {
116
121
  perspective: '透视视图',
117
122
  top: '顶视图 · 自动切换正交',
123
+ bottom: '底视图 · 自动切换正交',
118
124
  front: '前视图 · 自动切换正交',
125
+ back: '后视图 · 自动切换正交',
126
+ left: '左视图 · 自动切换正交',
119
127
  right: '右视图 · 自动切换正交',
128
+ iso: '等距视图 · 自动切换正交',
129
+ threeQuarterTop: '斜 45° 俯视图',
120
130
  };
121
131
  const VIEWPORT_OVERLAY_TOGGLE_LABELS = {
122
132
  bounds: '包围盒',
@@ -170,6 +180,50 @@ function setToolbarButtonTooltip(button, tooltip) {
170
180
  button.dataset.editorTooltip = tooltip;
171
181
  button.setAttribute('aria-label', tooltip);
172
182
  }
183
+ function createAgentBridgeStatusTooltip(status) {
184
+ const label = formatAgentBridgeStatusLabel(status?.status);
185
+ const details = [
186
+ `Agent Bridge:${label}`,
187
+ status?.url ? `URL ${status.url}` : '',
188
+ status?.sessionId ? `Session ${status.sessionId}` : '',
189
+ status ? `Capabilities ${status.capabilityCount}` : '',
190
+ status?.lastError ? `Error ${status.lastError}` : '',
191
+ status?.connectedAt ? `Connected ${status.connectedAt}` : '',
192
+ status?.lastChangedAt ? `Updated ${status.lastChangedAt}` : '',
193
+ ].filter(Boolean);
194
+ return details.join(' · ');
195
+ }
196
+ function formatAgentBridgeStatusLabel(status) {
197
+ switch (status) {
198
+ case 'disabled':
199
+ return '未启用';
200
+ case 'connecting':
201
+ return '连接中';
202
+ case 'connected':
203
+ return '已连接';
204
+ case 'disconnected':
205
+ return '已断开';
206
+ case 'error':
207
+ return '错误';
208
+ default:
209
+ return '未知';
210
+ }
211
+ }
212
+ function resolveAgentBridgeStatusToneColor(status) {
213
+ switch (status?.status) {
214
+ case 'connected':
215
+ return 'var(--fps-editor-success)';
216
+ case 'connecting':
217
+ return 'var(--fps-editor-accent-strong)';
218
+ case 'disconnected':
219
+ return 'var(--fps-editor-warn)';
220
+ case 'error':
221
+ return 'var(--fps-editor-danger-strong)';
222
+ case 'disabled':
223
+ default:
224
+ return 'var(--fps-editor-muted)';
225
+ }
226
+ }
173
227
  function setToolbarButtonIcon(doc, button, icon) {
174
228
  const currentIcon = button.querySelector('[data-editor-icon]');
175
229
  if (currentIcon?.dataset.editorIcon === icon)
@@ -2023,6 +2077,7 @@ export function createAssetBrowserMenuItems(state, asset) {
2023
2077
  const assetKind = resolveLocalEditorBrowserAssetKind(asset);
2024
2078
  const placeable = asset.placeable !== false && asset.disabled !== true;
2025
2079
  const activeId = state.activeId;
2080
+ const inPrefabStage = !!state.prefabStage;
2026
2081
  const items = [];
2027
2082
  if (assetKind === 'material') {
2028
2083
  const deleteDisabledReason = getMaterialAssetDeleteDisabledReason(asset);
@@ -2054,9 +2109,24 @@ export function createAssetBrowserMenuItems(state, asset) {
2054
2109
  });
2055
2110
  }
2056
2111
  else if (assetKind === 'prefab') {
2112
+ if (inPrefabStage) {
2113
+ items.push({
2114
+ id: 'asset.add-to-current-prefab',
2115
+ label: '添加到当前 Prefab',
2116
+ disabled: !placeable,
2117
+ disabledReason: '该 Prefab 当前不可添加到当前 Prefab。',
2118
+ });
2119
+ }
2120
+ items.push({
2121
+ id: 'asset.rename',
2122
+ label: '重命名 Prefab',
2123
+ disabled: !asset.assetId && !asset.id,
2124
+ disabledReason: '该预制体资产缺少可重命名的资产 ID。',
2125
+ });
2057
2126
  items.push({
2058
2127
  id: 'asset.edit-prefab',
2059
- label: '编辑 Prefab',
2128
+ label: inPrefabStage ? '打开 Prefab Stage' : '编辑 Prefab',
2129
+ separatorBefore: inPrefabStage ? true : undefined,
2060
2130
  disabled: !asset.prefab,
2061
2131
  disabledReason: '该预制体资产缺少可编辑参数。',
2062
2132
  });
@@ -2077,19 +2147,21 @@ export function createAssetBrowserMenuItems(state, asset) {
2077
2147
  });
2078
2148
  }
2079
2149
  else if (assetKind === 'texture') {
2080
- items.push({
2081
- id: 'asset.add-to-scene',
2082
- label: '作为地贴添加到场景',
2083
- separatorBefore: asset.preview ? true : undefined,
2084
- disabled: !placeable,
2085
- disabledReason: '该贴图当前不可放置。',
2086
- });
2087
- items.push({
2088
- id: 'asset.place',
2089
- label: '进入地面放置模式',
2090
- disabled: !placeable,
2091
- disabledReason: '该贴图当前不可放置。',
2092
- });
2150
+ if (!inPrefabStage) {
2151
+ items.push({
2152
+ id: 'asset.add-to-scene',
2153
+ label: '作为地贴添加到场景',
2154
+ separatorBefore: asset.preview ? true : undefined,
2155
+ disabled: !placeable,
2156
+ disabledReason: '该贴图当前不可放置。',
2157
+ });
2158
+ items.push({
2159
+ id: 'asset.place',
2160
+ label: '进入地面放置模式',
2161
+ disabled: !placeable,
2162
+ disabledReason: '该贴图当前不可放置。',
2163
+ });
2164
+ }
2093
2165
  items.push({
2094
2166
  id: 'asset.use-base-texture',
2095
2167
  label: '用作当前材质 Base 图',
@@ -2105,52 +2177,64 @@ export function createAssetBrowserMenuItems(state, asset) {
2105
2177
  });
2106
2178
  }
2107
2179
  else if (assetKind === 'prefab') {
2108
- items.push({
2109
- id: 'asset.add-to-scene',
2110
- label: '添加 Prefab 到场景',
2111
- separatorBefore: true,
2112
- disabled: !placeable,
2113
- disabledReason: '该 Prefab 当前不可放置。',
2114
- });
2115
- items.push({
2116
- id: 'asset.place',
2117
- label: '进入 Prefab 放置模式',
2118
- disabled: !placeable,
2119
- disabledReason: '该 Prefab 当前不可放置。',
2120
- });
2180
+ if (!inPrefabStage) {
2181
+ items.push({
2182
+ id: 'asset.add-to-scene',
2183
+ label: '添加 Prefab 到场景',
2184
+ separatorBefore: true,
2185
+ disabled: !placeable,
2186
+ disabledReason: '该 Prefab 当前不可放置。',
2187
+ });
2188
+ items.push({
2189
+ id: 'asset.place',
2190
+ label: '进入 Prefab 放置模式',
2191
+ disabled: !placeable,
2192
+ disabledReason: '该 Prefab 当前不可放置。',
2193
+ });
2194
+ }
2121
2195
  }
2122
2196
  else {
2123
- items.push({
2124
- id: 'asset.add-to-scene',
2125
- label: '添加到场景',
2126
- disabled: !placeable,
2127
- disabledReason: '该模型当前不可放置。',
2128
- });
2129
- items.push({
2130
- id: 'asset.place',
2131
- label: '进入放置模式',
2132
- disabled: !placeable,
2133
- disabledReason: '该模型当前不可放置。',
2134
- });
2135
- items.push({
2136
- id: 'asset.create-prefab',
2137
- label: '创建 Prefab',
2138
- disabled: !asset.assetId && !asset.id,
2139
- disabledReason: '该模型缺少可创建 Prefab 的 Asset ID。',
2140
- separatorBefore: true,
2141
- });
2142
- items.push({
2143
- id: 'asset.add-as-child',
2144
- label: '添加为当前节点子对象',
2145
- disabled: true,
2146
- disabledReason: '子对象添加动作将在资产 patch 中接入。',
2147
- });
2148
- items.push({
2149
- id: 'asset.replace-selected-model',
2150
- label: '替换当前模型',
2151
- disabled: true,
2152
- disabledReason: '模型替换动作将在资产 patch 中接入。',
2153
- });
2197
+ if (inPrefabStage) {
2198
+ items.push({
2199
+ id: 'asset.add-to-current-prefab',
2200
+ label: '添加到当前 Prefab',
2201
+ disabled: !placeable,
2202
+ disabledReason: '该模型当前不可添加到当前 Prefab。',
2203
+ });
2204
+ }
2205
+ if (!inPrefabStage) {
2206
+ items.push({
2207
+ id: 'asset.add-to-scene',
2208
+ label: '添加到场景',
2209
+ disabled: !placeable,
2210
+ disabledReason: '该模型当前不可放置。',
2211
+ });
2212
+ items.push({
2213
+ id: 'asset.place',
2214
+ label: '进入放置模式',
2215
+ disabled: !placeable,
2216
+ disabledReason: '该模型当前不可放置。',
2217
+ });
2218
+ items.push({
2219
+ id: 'asset.create-prefab',
2220
+ label: '创建 Prefab',
2221
+ disabled: !asset.assetId && !asset.id,
2222
+ disabledReason: '该模型缺少可创建 Prefab 的 Asset ID。',
2223
+ separatorBefore: true,
2224
+ });
2225
+ items.push({
2226
+ id: 'asset.add-as-child',
2227
+ label: '添加为当前节点子对象',
2228
+ disabled: true,
2229
+ disabledReason: '子对象添加动作将在资产 patch 中接入。',
2230
+ });
2231
+ items.push({
2232
+ id: 'asset.replace-selected-model',
2233
+ label: '替换当前模型',
2234
+ disabled: true,
2235
+ disabledReason: '模型替换动作将在资产 patch 中接入。',
2236
+ });
2237
+ }
2154
2238
  }
2155
2239
  items.push({
2156
2240
  id: 'asset.copy-id',
@@ -2171,14 +2255,24 @@ function getMaterialAssetDeleteDisabledReason(asset) {
2171
2255
  return `该材质正在被 ${usageCount} 处使用,请先替换或解绑。`;
2172
2256
  return undefined;
2173
2257
  }
2174
- function createAssetBrowserActionInput(actionId, asset) {
2258
+ function createAssetBrowserActionInput(actionId, asset, context) {
2175
2259
  return {
2176
2260
  actionId,
2177
2261
  assetId: asset.assetId ?? asset.id,
2178
2262
  browserAssetId: asset.id,
2179
2263
  assetKind: asset.kind ?? resolveLocalEditorBrowserAssetKind(asset),
2264
+ ...(context?.targetPrefabAssetId ? { targetPrefabAssetId: context.targetPrefabAssetId } : {}),
2265
+ ...(context?.parentNodeId ? { parentNodeId: context.parentNodeId } : {}),
2180
2266
  };
2181
2267
  }
2268
+ export function resolveAssetBrowserDoubleClickAction(state, asset) {
2269
+ const assetKind = resolveLocalEditorBrowserAssetKind(asset);
2270
+ if (state.prefabStage && (assetKind === 'model' || assetKind === 'prefab'))
2271
+ return 'asset.add-to-current-prefab';
2272
+ if (!state.prefabStage && assetKind === 'prefab')
2273
+ return 'asset.edit-prefab';
2274
+ return null;
2275
+ }
2182
2276
  function copyTextToClipboard(win, text) {
2183
2277
  void win?.navigator?.clipboard?.writeText?.(text);
2184
2278
  }
@@ -2392,11 +2486,14 @@ export function createLocalEditorBrowserUi(options = {}) {
2392
2486
  let assetPickerFilter = '';
2393
2487
  let assetPickerInput = null;
2394
2488
  let assetPickerProperty = null;
2395
- let prefabStageExplorerFilter = '';
2396
2489
  let prefabComparisonPreviewDrag = null;
2490
+ let prefabStageMainWorkbenchLayoutSnapshot = null;
2397
2491
  const editorStatusButton = createToolbarIconButton(doc, '编辑器状态', 'status', '编辑器状态');
2398
2492
  editorStatusButton.dataset.editorStatusButton = 'true';
2399
2493
  editorStatusButton.style.cursor = 'help';
2494
+ const agentBridgeStatusButton = createToolbarIconButton(doc, 'Agent Bridge 状态', 'status', 'Agent Bridge 状态');
2495
+ agentBridgeStatusButton.dataset.editorAgentBridgeStatusButton = 'true';
2496
+ agentBridgeStatusButton.style.cursor = 'help';
2400
2497
  const workbench = createLocalEditorWorkbench(doc);
2401
2498
  const leftDockTabs = doc.createElement('div');
2402
2499
  const hierarchyPanel = createWorkbenchPanelContent(doc);
@@ -3035,6 +3132,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3035
3132
  sceneToolOverlay.appendChild(viewportToolsGroup);
3036
3133
  sceneToolOverlay.appendChild(sceneUtilityActions);
3037
3134
  sceneToolOverlay.appendChild(cameraPreviewGroup);
3135
+ sceneToolOverlay.appendChild(agentBridgeStatusButton);
3038
3136
  sceneToolOverlay.appendChild(editorStatusButton);
3039
3137
  sceneToolOverlay.appendChild(toolbarOverflowButton);
3040
3138
  workbench.sceneHeader.appendChild(sceneToolOverlay);
@@ -3460,6 +3558,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3460
3558
  viewportToolsGroup,
3461
3559
  sceneUtilityActions,
3462
3560
  cameraPreviewGroup,
3561
+ agentBridgeStatusButton,
3463
3562
  editorStatusButton,
3464
3563
  toolbarOverflowButton,
3465
3564
  ];
@@ -3473,6 +3572,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3473
3572
  { id: 'snap', element: snapGroup, kind: 'group' },
3474
3573
  { id: 'space', element: spaceGroup, kind: 'group' },
3475
3574
  { id: 'static-shadow-bake', element: staticShadowBakeGroup, kind: 'group' },
3575
+ { id: 'agent-bridge-status', element: agentBridgeStatusButton, kind: 'group' },
3476
3576
  ];
3477
3577
  let toolbarOverflowOpen = false;
3478
3578
  let toolbarOverflowRaf = null;
@@ -3896,6 +3996,20 @@ export function createLocalEditorBrowserUi(options = {}) {
3896
3996
  syncInputModalOpen();
3897
3997
  assetPreviewCloseButton.focus({ preventScroll: true });
3898
3998
  };
3999
+ const openAssetRenameModal = (asset) => {
4000
+ contextMenu.close();
4001
+ previewedAsset = asset;
4002
+ assetPreviewMode = 'rename';
4003
+ assetPreviewDialog.setAttribute('aria-label', '重命名资产');
4004
+ assetPreviewOpen = true;
4005
+ renderAssetPreviewModal();
4006
+ syncInputModalOpen();
4007
+ setTimeout(() => {
4008
+ const input = assetPreviewBody.querySelector('[data-editor-asset-rename-input]');
4009
+ input?.focus({ preventScroll: true });
4010
+ input?.select();
4011
+ }, 0);
4012
+ };
3899
4013
  const closeAssetPreviewModal = () => {
3900
4014
  if (!assetPreviewOpen)
3901
4015
  return;
@@ -3960,6 +4074,11 @@ export function createLocalEditorBrowserUi(options = {}) {
3960
4074
  assetPreviewModal.style.display = 'flex';
3961
4075
  return;
3962
4076
  }
4077
+ if (assetPreviewMode === 'rename') {
4078
+ renderAssetRenameModal(asset);
4079
+ assetPreviewModal.style.display = 'flex';
4080
+ return;
4081
+ }
3963
4082
  assetPreviewDialog.style.width = 'min(420px,calc(100vw - 64px))';
3964
4083
  assetPreviewBody.style.cssText = [
3965
4084
  'display:flex',
@@ -3980,6 +4099,49 @@ export function createLocalEditorBrowserUi(options = {}) {
3980
4099
  assetPreviewBody.appendChild(LocalEditorPanels.createAssetPreviewElement(doc, asset, 'modal'));
3981
4100
  assetPreviewModal.style.display = 'flex';
3982
4101
  }
4102
+ function renderAssetRenameModal(asset) {
4103
+ assetPreviewDialog.style.width = 'min(420px,calc(100vw - 64px))';
4104
+ assetPreviewTitle.textContent = '重命名 Prefab';
4105
+ assetPreviewMeta.textContent = asset.assetId ?? asset.id;
4106
+ while (assetPreviewBody.firstChild)
4107
+ assetPreviewBody.removeChild(assetPreviewBody.firstChild);
4108
+ assetPreviewBody.style.cssText = [
4109
+ 'display:flex',
4110
+ 'align-items:stretch',
4111
+ 'justify-content:stretch',
4112
+ 'min-height:0',
4113
+ 'border:1px solid var(--fps-editor-divider)',
4114
+ 'border-radius:4px',
4115
+ 'background:var(--fps-editor-panel-soft)',
4116
+ 'padding:12px',
4117
+ ].join(';');
4118
+ const form = doc.createElement('form');
4119
+ form.dataset.editorAssetRenameForm = 'true';
4120
+ form.style.cssText = 'display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;width:100%;align-items:center';
4121
+ const input = doc.createElement('input');
4122
+ input.type = 'text';
4123
+ input.dataset.editorAssetRenameInput = 'true';
4124
+ input.value = asset.label;
4125
+ input.maxLength = 80;
4126
+ input.required = true;
4127
+ input.style.cssText = [
4128
+ 'height:30px',
4129
+ 'min-width:0',
4130
+ 'box-sizing:border-box',
4131
+ 'border:1px solid var(--fps-editor-border)',
4132
+ 'border-radius:3px',
4133
+ 'background:var(--fps-editor-field)',
4134
+ 'color:var(--fps-editor-text)',
4135
+ 'font-size:12px',
4136
+ 'padding:0 8px',
4137
+ 'outline:none',
4138
+ ].join(';');
4139
+ const submit = LocalEditorShared.createButton(doc, '确认');
4140
+ submit.type = 'submit';
4141
+ form.appendChild(input);
4142
+ form.appendChild(submit);
4143
+ assetPreviewBody.appendChild(form);
4144
+ }
3983
4145
  function renderAssetMaterialEditorModal(asset) {
3984
4146
  const material = asset.material;
3985
4147
  const profile = material.profile ?? {};
@@ -4377,6 +4539,24 @@ export function createLocalEditorBrowserUi(options = {}) {
4377
4539
  return;
4378
4540
  dispatchMaterialEditorFieldChange(input);
4379
4541
  });
4542
+ assetPreviewBody.addEventListener('submit', (event) => {
4543
+ if (assetPreviewMode !== 'rename')
4544
+ return;
4545
+ event.preventDefault();
4546
+ const asset = resolvePreviewedAssetFromState();
4547
+ const form = event.target instanceof HTMLFormElement
4548
+ ? event.target.closest('[data-editor-asset-rename-form]')
4549
+ : null;
4550
+ const input = form?.querySelector('[data-editor-asset-rename-input]');
4551
+ const name = input?.value.trim() ?? '';
4552
+ if (!asset || !name)
4553
+ return;
4554
+ callbacks.onAssetAction?.({
4555
+ ...createAssetBrowserActionInput('asset.rename', asset),
4556
+ value: name,
4557
+ });
4558
+ closeAssetPreviewModal();
4559
+ });
4380
4560
  assetPickerModal.addEventListener('click', (event) => {
4381
4561
  const target = event.target instanceof HTMLElement ? event.target : null;
4382
4562
  if (target?.closest('[data-editor-asset-picker-close]')) {
@@ -4491,6 +4671,18 @@ export function createLocalEditorBrowserUi(options = {}) {
4491
4671
  return;
4492
4672
  }
4493
4673
  }
4674
+ function createCurrentAssetBrowserActionContext() {
4675
+ const stage = currentState?.prefabStage;
4676
+ if (!stage)
4677
+ return undefined;
4678
+ const selectedItem = findLocalEditorPrefabStageStructureItem(stage, stage.selectedItemId);
4679
+ return {
4680
+ targetPrefabAssetId: stage.assetId,
4681
+ ...(selectedItem?.itemType === 'prefab-node' && selectedItem.nodeId
4682
+ ? { parentNodeId: selectedItem.nodeId }
4683
+ : {}),
4684
+ };
4685
+ }
4494
4686
  assetPanel.addEventListener('click', (event) => {
4495
4687
  const target = event.target instanceof HTMLElement ? event.target : null;
4496
4688
  const tabButton = target?.closest('[data-editor-dock-tab]');
@@ -4524,6 +4716,22 @@ export function createLocalEditorBrowserUi(options = {}) {
4524
4716
  return;
4525
4717
  }
4526
4718
  });
4719
+ assetPanel.addEventListener('dblclick', (event) => {
4720
+ const target = event.target instanceof HTMLElement ? event.target : null;
4721
+ const assetButton = target?.closest('[data-editor-asset-id]');
4722
+ const browserAssetId = assetButton?.dataset.editorAssetId;
4723
+ if (!browserAssetId || !currentState)
4724
+ return;
4725
+ const asset = currentState.assets.find(candidate => candidate.id === browserAssetId);
4726
+ const actionId = asset ? resolveAssetBrowserDoubleClickAction(currentState, asset) : null;
4727
+ if (!asset || !actionId)
4728
+ return;
4729
+ event.preventDefault();
4730
+ event.stopPropagation();
4731
+ suppressAssetBrowserRevealIfVisible(assetButton);
4732
+ callbacks.onSelectAsset?.(browserAssetId);
4733
+ callbacks.onAssetAction?.(createAssetBrowserActionInput(actionId, asset, createCurrentAssetBrowserActionContext()));
4734
+ });
4527
4735
  assetPanel.addEventListener('contextmenu', (event) => {
4528
4736
  const target = event.target instanceof HTMLElement ? event.target : null;
4529
4737
  const assetButton = target?.closest('[data-editor-asset-id]');
@@ -4550,15 +4758,19 @@ export function createLocalEditorBrowserUi(options = {}) {
4550
4758
  openAssetMaterialEditorModal(asset);
4551
4759
  return;
4552
4760
  }
4553
- if (item.id === 'asset.edit-prefab') {
4554
- callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset));
4761
+ if (item.id === 'asset.rename') {
4762
+ openAssetRenameModal(asset);
4763
+ return;
4764
+ }
4765
+ if (item.id === 'asset.edit-prefab' || item.id === 'asset.add-to-current-prefab') {
4766
+ callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset, createCurrentAssetBrowserActionContext()));
4555
4767
  return;
4556
4768
  }
4557
4769
  if (item.id === 'asset.copy-id') {
4558
4770
  copyTextToClipboard(doc.defaultView, asset.assetId ?? asset.id);
4559
4771
  return;
4560
4772
  }
4561
- callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset));
4773
+ callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset, createCurrentAssetBrowserActionContext()));
4562
4774
  },
4563
4775
  });
4564
4776
  });
@@ -4582,12 +4794,6 @@ export function createLocalEditorBrowserUi(options = {}) {
4582
4794
  });
4583
4795
  workbench.leftDock.addEventListener('click', (event) => {
4584
4796
  const target = event.target instanceof HTMLElement ? event.target : null;
4585
- const prefabStageItem = target?.closest('[data-editor-prefab-stage-item]');
4586
- const prefabStageItemId = prefabStageItem?.dataset.editorPrefabStageItem;
4587
- if (prefabStageItemId) {
4588
- callbacks.onSelectPrefabStageItem?.(prefabStageItemId);
4589
- return;
4590
- }
4591
4797
  const tabButton = target?.closest('[data-editor-left-dock-tab]');
4592
4798
  const tab = tabButton?.dataset.editorLeftDockTab;
4593
4799
  if (tab === 'hierarchy') {
@@ -4596,15 +4802,6 @@ export function createLocalEditorBrowserUi(options = {}) {
4596
4802
  render(currentState);
4597
4803
  }
4598
4804
  });
4599
- workbench.leftDock.addEventListener('input', (event) => {
4600
- const target = event.target instanceof HTMLElement ? event.target : null;
4601
- const input = target?.closest('[data-editor-prefab-stage-explorer-search]');
4602
- if (!input)
4603
- return;
4604
- prefabStageExplorerFilter = input.value;
4605
- if (currentState)
4606
- render(currentState);
4607
- });
4608
4805
  const hierarchyController = createLocalEditorHierarchyController({
4609
4806
  doc,
4610
4807
  panel: hierarchyPanel,
@@ -4974,11 +5171,6 @@ export function createLocalEditorBrowserUi(options = {}) {
4974
5171
  closeStaticShadowBakePopover();
4975
5172
  return;
4976
5173
  }
4977
- if (key === 'escape' && currentState?.prefabStage) {
4978
- event.preventDefault();
4979
- callbacks.onExitPrefabStage?.();
4980
- return;
4981
- }
4982
5174
  const primaryModifier = event.metaKey || event.ctrlKey;
4983
5175
  const handleDocumentShortcut = inputRouter.shouldHandleDocumentShortcut(event);
4984
5176
  const handleGlobalShortcut = inputRouter.shouldHandleGlobalShortcut(event);
@@ -4995,7 +5187,11 @@ export function createLocalEditorBrowserUi(options = {}) {
4995
5187
  setPrefabComparisonPreviewOpen(!prefabComparisonPreviewOpen);
4996
5188
  return;
4997
5189
  }
4998
- if (handleDocumentShortcut && localTestActionsEnabled && primaryModifier && key === 's') {
5190
+ if (handleDocumentShortcut
5191
+ && localTestActionsEnabled
5192
+ && isPreviewToolEnabled('local-test')
5193
+ && primaryModifier
5194
+ && key === 's') {
4999
5195
  event.preventDefault();
5000
5196
  callbacks.onSaveScene?.();
5001
5197
  return;
@@ -5027,8 +5223,6 @@ export function createLocalEditorBrowserUi(options = {}) {
5027
5223
  if (!currentState.prefabStage && handleGlobalShortcut && hierarchyController.handleEditShortcut(event)) {
5028
5224
  return;
5029
5225
  }
5030
- if (currentState.prefabStage)
5031
- return;
5032
5226
  if (!handleGlobalShortcut || event.metaKey || event.ctrlKey || event.altKey)
5033
5227
  return;
5034
5228
  const toolByKey = {
@@ -5040,20 +5234,24 @@ export function createLocalEditorBrowserUi(options = {}) {
5040
5234
  const tool = toolByKey[key];
5041
5235
  if (tool) {
5042
5236
  event.preventDefault();
5043
- callbacks.onTransformToolChange?.(tool);
5237
+ if (isPreviewToolEnabled(tool))
5238
+ callbacks.onTransformToolChange?.(tool);
5044
5239
  return;
5045
5240
  }
5046
5241
  if (key === 'f') {
5047
5242
  event.preventDefault();
5048
- callbacks.onFocusSelection?.();
5243
+ if (isPreviewToolEnabled('focus-selection'))
5244
+ callbacks.onFocusSelection?.();
5049
5245
  return;
5050
5246
  }
5051
5247
  if (key === 'escape') {
5052
5248
  event.preventDefault();
5053
- if (callbacks.onCancelEditorIntent)
5054
- callbacks.onCancelEditorIntent();
5055
- else
5056
- callbacks.onCancelActiveOperation?.();
5249
+ if (isPreviewToolEnabled('cancel-selection')) {
5250
+ if (callbacks.onCancelEditorIntent)
5251
+ callbacks.onCancelEditorIntent();
5252
+ else
5253
+ callbacks.onCancelActiveOperation?.();
5254
+ }
5057
5255
  }
5058
5256
  };
5059
5257
  doc.addEventListener('keydown', onKeyDown);
@@ -5070,12 +5268,23 @@ export function createLocalEditorBrowserUi(options = {}) {
5070
5268
  ? operationState.canAlign
5071
5269
  : operationState.canDistribute;
5072
5270
  }
5271
+ function getPreviewToolSupport(tool) {
5272
+ const inPrefabStage = currentState?.mode === 'editor' && !!currentState.prefabStage;
5273
+ return resolveLocalEditorPreviewToolSupport({ inPrefabStage, tool });
5274
+ }
5275
+ function isPreviewToolVisible(tool) {
5276
+ return currentState?.mode === 'editor' && getPreviewToolSupport(tool).support !== 'hidden';
5277
+ }
5278
+ function isPreviewToolEnabled(tool) {
5279
+ return currentState?.mode === 'editor'
5280
+ && currentState.busy !== true
5281
+ && getPreviewToolSupport(tool).support === 'enabled';
5282
+ }
5073
5283
  function applyPrefabStageWorkbenchLayoutOverride(layout = workbenchLayoutController.getLayout()) {
5074
- const leftWidth = Math.min(Math.max(layout.leftWidth, 220), 420);
5075
- const rightWidth = Math.min(Math.max(layout.rightWidth, 300), 520);
5284
+ const { leftWidth, rightWidth, bottomEdge, bottomVisible } = resolveLocalEditorPrefabStageWorkbenchLayout(layout, readLocalEditorWorkbenchViewport(doc));
5076
5285
  workbench.leftDock.style.display = 'flex';
5077
5286
  workbench.leftDock.style.width = `${leftWidth}px`;
5078
- workbench.leftDock.style.bottom = '0';
5287
+ workbench.leftDock.style.bottom = `${bottomEdge}px`;
5079
5288
  workbench.leftDock.style.zIndex = '';
5080
5289
  workbench.leftDock.style.boxShadow = '';
5081
5290
  workbench.rightDock.style.display = 'flex';
@@ -5084,116 +5293,22 @@ export function createLocalEditorBrowserUi(options = {}) {
5084
5293
  workbench.rightDock.style.boxShadow = '';
5085
5294
  workbench.sceneFrame.style.left = `${leftWidth}px`;
5086
5295
  workbench.sceneFrame.style.right = `${rightWidth}px`;
5087
- workbench.sceneFrame.style.bottom = '0';
5088
- workbench.bottomDock.style.display = 'none';
5089
- workbench.bottomResizer.style.display = 'none';
5090
- workbench.bottomToggle.style.display = 'none';
5296
+ workbench.sceneFrame.style.bottom = `${bottomEdge}px`;
5297
+ if (bottomVisible) {
5298
+ workbench.bottomDock.style.right = `${rightWidth}px`;
5299
+ workbench.bottomResizer.style.right = `${rightWidth}px`;
5300
+ }
5091
5301
  workbench.leftToggle.style.display = 'none';
5092
5302
  workbench.rightToggle.style.display = 'none';
5093
- workbench.leftResizer.style.bottom = '0';
5303
+ workbench.leftResizer.style.bottom = `${bottomEdge}px`;
5094
5304
  workbench.rightResizer.style.bottom = '0';
5095
5305
  }
5096
- function renderPrefabStageStructurePanel(stage) {
5097
- LocalEditorShared.clearElement(hierarchyPanel);
5098
- hierarchyPanel.dataset.editorPanelId = 'prefab-explorer';
5099
- hierarchyPanel.appendChild(createPrefabStagePanelHeader('Prefab Explorer', 'hierarchy'));
5100
- const search = doc.createElement('input');
5101
- search.type = 'search';
5102
- search.dataset.editorPrefabStageExplorerSearch = 'true';
5103
- search.placeholder = 'Filter';
5104
- search.value = prefabStageExplorerFilter;
5105
- search.style.cssText = [
5106
- 'width:calc(100% - 16px)',
5107
- 'height:28px',
5108
- 'margin:6px 8px 8px',
5109
- 'padding:0 8px',
5110
- 'border:1px solid var(--fps-editor-border-strong)',
5111
- 'border-radius:0',
5112
- 'background:var(--fps-editor-input-bg)',
5113
- 'color:var(--fps-editor-text)',
5114
- 'font-size:12px',
5115
- 'font-weight:700',
5116
- 'outline:none',
5117
- ].join(';');
5118
- hierarchyPanel.appendChild(search);
5119
- if (stage.importStructureReady === false) {
5120
- const loading = doc.createElement('div');
5121
- loading.textContent = 'Loading import structure...';
5122
- loading.style.cssText = 'padding:0 8px 8px;color:var(--fps-editor-muted);font-size:11px;font-weight:800';
5123
- hierarchyPanel.appendChild(loading);
5124
- }
5125
- const list = doc.createElement('div');
5126
- list.style.cssText = 'display:flex;flex-direction:column;gap:1px';
5127
- const visibleItems = filterLocalEditorPrefabStageStructureItems(stage.structureItems, prefabStageExplorerFilter);
5128
- const renderItem = (item, depth) => {
5129
- const button = doc.createElement('button');
5130
- button.type = 'button';
5131
- button.dataset.editorPrefabStageItem = item.id;
5132
- const selected = stage.selectedItemId === item.id;
5133
- const icon = isLocalEditorIconName(item.icon)
5134
- ? item.icon
5135
- : item.kind === 'root'
5136
- ? 'prefab'
5137
- : item.kind === 'source'
5138
- ? 'asset'
5139
- : item.kind === 'material'
5140
- ? 'material-slot'
5141
- : item.kind === 'texture'
5142
- ? 'asset'
5143
- : item.kind === 'animation'
5144
- ? 'execute'
5145
- : item.kind === 'group'
5146
- ? 'group'
5147
- : 'object';
5148
- button.style.cssText = [
5149
- 'width:100%',
5150
- 'min-height:26px',
5151
- 'display:flex',
5152
- 'align-items:center',
5153
- 'gap:6px',
5154
- `padding:3px 8px 3px ${8 + depth * 16}px`,
5155
- `border:1px solid ${selected ? 'var(--fps-editor-accent)' : 'transparent'}`,
5156
- 'border-radius:0',
5157
- `background:${selected ? 'var(--fps-editor-row-selected)' : 'transparent'}`,
5158
- `color:${selected ? 'var(--fps-editor-row-selected-text)' : 'var(--fps-editor-text)'}`,
5159
- 'font-size:12px',
5160
- 'font-weight:800',
5161
- 'text-align:left',
5162
- 'cursor:pointer',
5163
- 'overflow:hidden',
5164
- ].join(';');
5165
- button.appendChild(createLocalEditorIcon(doc, icon, { size: 14 }));
5166
- const label = doc.createElement('span');
5167
- label.textContent = item.label;
5168
- label.style.cssText = 'min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1';
5169
- button.appendChild(label);
5170
- if (item.readonly === true) {
5171
- const readonlyBadge = doc.createElement('span');
5172
- readonlyBadge.textContent = 'READONLY';
5173
- readonlyBadge.style.cssText = [
5174
- 'flex:0 0 auto',
5175
- 'padding:1px 4px',
5176
- 'border-radius:2px',
5177
- 'background:var(--fps-editor-chip-bg)',
5178
- 'color:var(--fps-editor-muted-strong)',
5179
- 'font-size:9px',
5180
- 'font-weight:900',
5181
- ].join(';');
5182
- button.appendChild(readonlyBadge);
5183
- }
5184
- list.appendChild(button);
5185
- for (const child of item.children ?? [])
5186
- renderItem(child, depth + 1);
5306
+ function readLocalEditorWorkbenchViewport(docRef) {
5307
+ const win = docRef.defaultView;
5308
+ return {
5309
+ width: Math.max(320, win?.innerWidth ?? docRef.documentElement.clientWidth ?? 1280),
5310
+ height: Math.max(320, win?.innerHeight ?? docRef.documentElement.clientHeight ?? 720),
5187
5311
  };
5188
- for (const item of visibleItems)
5189
- renderItem(item, 0);
5190
- if (visibleItems.length === 0) {
5191
- const empty = doc.createElement('div');
5192
- empty.textContent = prefabStageExplorerFilter.trim() ? 'No matching items.' : 'No structure available.';
5193
- empty.style.cssText = 'padding:8px;color:var(--fps-editor-muted);font-size:12px;font-weight:800';
5194
- list.appendChild(empty);
5195
- }
5196
- hierarchyPanel.appendChild(list);
5197
5312
  }
5198
5313
  function renderPrefabStagePropertiesPanel(stage) {
5199
5314
  inspectorPanel.dataset.editorPanelId = 'prefab-properties';
@@ -5382,6 +5497,13 @@ export function createLocalEditorBrowserUi(options = {}) {
5382
5497
  editorStatusButton.style.borderColor = state.statusTone == null || state.statusTone === 'default'
5383
5498
  ? 'var(--fps-editor-border)'
5384
5499
  : statusToneColor;
5500
+ const agentBridgeStatusColor = resolveAgentBridgeStatusToneColor(state.agentBridge);
5501
+ agentBridgeStatusButton.style.display = inEditor ? 'inline-flex' : 'none';
5502
+ agentBridgeStatusButton.style.color = agentBridgeStatusColor;
5503
+ agentBridgeStatusButton.style.borderColor = state.agentBridge?.status === 'disabled'
5504
+ ? 'var(--fps-editor-border)'
5505
+ : agentBridgeStatusColor;
5506
+ setToolbarButtonTooltip(agentBridgeStatusButton, createAgentBridgeStatusTooltip(state.agentBridge));
5385
5507
  renderCoordinateAxesOverlay(coordinateAxesOverlay, inEditor ? state.coordinateAxes ?? null : null);
5386
5508
  renderSceneFrameRateOverlay(sceneFrameRateOverlay, inEditor && !inPrefabStage ? state.sceneFrameStats ?? null : null);
5387
5509
  renderPerformanceMonitorOverlay(performanceMonitorOverlay, inEditor && !inPrefabStage ? state.performanceStats ?? null : null, inEditor && !inPrefabStage && performanceMonitorOpen);
@@ -5443,9 +5565,7 @@ export function createLocalEditorBrowserUi(options = {}) {
5443
5565
  const disabled = state.busy;
5444
5566
  const prefabStage = inEditor ? state.prefabStage ?? null : null;
5445
5567
  const inPrefabStage = !!prefabStage;
5446
- if (!inPrefabStage || previousState?.prefabStage?.assetId !== prefabStage.assetId) {
5447
- prefabStageExplorerFilter = '';
5448
- }
5568
+ const previousInPrefabStage = previousState?.mode === 'editor' && !!previousState.prefabStage;
5449
5569
  if (!inEditor || disabled)
5450
5570
  contextMenu.close();
5451
5571
  hostChrome.style.display = !inEditor && localTestActionsEnabled ? 'flex' : 'none';
@@ -5454,9 +5574,9 @@ export function createLocalEditorBrowserUi(options = {}) {
5454
5574
  button.style.display = 'inline-flex';
5455
5575
  button.disabled = disabled;
5456
5576
  }
5457
- localTestGroup.style.display = inEditor && !inPrefabStage && localTestActionsEnabled ? 'flex' : 'none';
5458
- localTestButton.disabled = disabled;
5459
- if (!inEditor || !localTestActionsEnabled)
5577
+ localTestGroup.style.display = isPreviewToolVisible('local-test') && localTestActionsEnabled ? 'flex' : 'none';
5578
+ localTestButton.disabled = !isPreviewToolEnabled('local-test') || !localTestActionsEnabled;
5579
+ if (!inEditor || !localTestActionsEnabled || localTestGroup.style.display === 'none')
5460
5580
  closeLocalTestMenu();
5461
5581
  if (!inEditor)
5462
5582
  helpOpen = false;
@@ -5478,6 +5598,14 @@ export function createLocalEditorBrowserUi(options = {}) {
5478
5598
  sceneTitle.textContent = createLocalEditorPrefabStageTitle(prefabStage);
5479
5599
  sceneToolOverlay.style.display = inEditor ? 'flex' : 'none';
5480
5600
  prefabStageBackButton.style.display = inPrefabStage ? 'inline-flex' : 'none';
5601
+ if (inPrefabStage && !previousInPrefabStage) {
5602
+ prefabStageMainWorkbenchLayoutSnapshot = workbenchLayoutController.getLayout();
5603
+ workbenchLayoutController.setBottomCollapsed(false);
5604
+ }
5605
+ else if (!inPrefabStage && previousInPrefabStage && prefabStageMainWorkbenchLayoutSnapshot) {
5606
+ workbenchLayoutController.setLayout(prefabStageMainWorkbenchLayoutSnapshot, true);
5607
+ prefabStageMainWorkbenchLayoutSnapshot = null;
5608
+ }
5481
5609
  workbench.leftToggle.style.display = '';
5482
5610
  workbench.rightToggle.style.display = '';
5483
5611
  workbench.bottomToggle.style.display = '';
@@ -5495,34 +5623,40 @@ export function createLocalEditorBrowserUi(options = {}) {
5495
5623
  if (!inEditor)
5496
5624
  closeStaticShadowBakePopover();
5497
5625
  const staticShadowBakeAction = findLocalEditorRenderingAction(state.renderingPanel, STATIC_SHADOW_BAKE_ACTION_ID);
5498
- const staticShadowBakeVisible = inEditor && !inPrefabStage && !!staticShadowBakeAction;
5626
+ const staticShadowBakeVisible = isPreviewToolVisible('static-shadow-bake') && !!staticShadowBakeAction;
5499
5627
  staticShadowBakeGroup.style.display = staticShadowBakeVisible ? 'flex' : 'none';
5500
- const staticShadowBakeDisabled = disabled || !staticShadowBakeAction || staticShadowBakeAction.action.disabled === true;
5628
+ const staticShadowBakeSupport = getPreviewToolSupport('static-shadow-bake');
5629
+ const staticShadowBakeDisabled = !isPreviewToolEnabled('static-shadow-bake') || !staticShadowBakeAction || staticShadowBakeAction.action.disabled === true;
5501
5630
  staticShadowBakeButton.disabled = staticShadowBakeDisabled;
5502
5631
  staticShadowBakeButton.style.opacity = staticShadowBakeDisabled ? '0.62' : '1';
5503
5632
  staticShadowBakeButton.style.cursor = staticShadowBakeDisabled ? 'not-allowed' : 'pointer';
5504
5633
  const staticShadowBakeIcon = staticShadowBakeAction?.action.icon;
5505
5634
  setToolbarButtonIcon(doc, staticShadowBakeButton, isLocalEditorIconName(staticShadowBakeIcon) ? staticShadowBakeIcon : 'save');
5506
- setToolbarButtonTooltip(staticShadowBakeButton, staticShadowBakeAction?.action.tooltip ?? staticShadowBakeAction?.action.label ?? '烘焙静态阴影');
5635
+ setToolbarButtonTooltip(staticShadowBakeButton, staticShadowBakeSupport.support === 'enabled'
5636
+ ? staticShadowBakeAction?.action.tooltip ?? staticShadowBakeAction?.action.label ?? '烘焙静态阴影'
5637
+ : staticShadowBakeSupport.reason);
5507
5638
  LocalEditorShared.applyButtonActiveState(staticShadowBakeButton, !!staticShadowBakeAction?.system?.progress);
5508
5639
  renderStaticShadowBakePopover(state);
5509
5640
  const sceneCameraPreview = state.sceneCameraPreview ?? { enabled: false, available: false };
5510
- cameraPreviewGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5511
- sceneCameraButton.disabled = disabled || !sceneCameraPreview.available;
5641
+ cameraPreviewGroup.style.display = isPreviewToolVisible('scene-camera-preview') ? 'flex' : 'none';
5642
+ const sceneCameraPreviewSupport = getPreviewToolSupport('scene-camera-preview');
5643
+ sceneCameraButton.disabled = !isPreviewToolEnabled('scene-camera-preview') || !sceneCameraPreview.available;
5512
5644
  const sceneCameraTooltip = sceneCameraPreview.available
5513
5645
  ? '从 Main Camera 查看当前场景'
5514
5646
  : '当前场景没有可预览的 Main Camera';
5515
- setToolbarButtonTooltip(sceneCameraButton, sceneCameraTooltip);
5647
+ setToolbarButtonTooltip(sceneCameraButton, sceneCameraPreviewSupport.support === 'enabled'
5648
+ ? sceneCameraTooltip
5649
+ : sceneCameraPreviewSupport.reason);
5516
5650
  LocalEditorShared.applyButtonActiveState(sceneCameraButton, sceneCameraPreview.enabled);
5517
5651
  const viewportTools = state.viewportTools ?? null;
5518
- const viewportControlsDisabled = disabled || sceneCameraPreview.enabled;
5652
+ const viewportControlsDisabled = !isPreviewToolEnabled('viewport-camera') || sceneCameraPreview.enabled;
5519
5653
  const viewportControlsTooltip = sceneCameraPreview.enabled
5520
5654
  ? '当前为 Main Camera 预览,请关闭后再使用视口工具'
5521
5655
  : '';
5522
5656
  const viewportProjectionTooltip = sceneCameraPreview.enabled
5523
5657
  ? '当前为 Main Camera 预览,投影由 Main Camera 决定;关闭预览后可切换编辑视口投影'
5524
5658
  : '';
5525
- viewportToolsGroup.style.display = inEditor ? 'flex' : 'none';
5659
+ viewportToolsGroup.style.display = isPreviewToolVisible('viewport-camera') ? 'flex' : 'none';
5526
5660
  for (const [preset, button] of viewportPresetButtons) {
5527
5661
  button.disabled = viewportControlsDisabled;
5528
5662
  setToolbarButtonTooltip(button, viewportControlsTooltip || VIEW_PRESET_TOOLTIPS[preset]);
@@ -5538,12 +5672,12 @@ export function createLocalEditorBrowserUi(options = {}) {
5538
5672
  markerVisibilityButton.disabled = disabled;
5539
5673
  setToolbarButtonTooltip(markerVisibilityButton, markersVisible ? '隐藏标记与关系线' : '显示标记与关系线');
5540
5674
  LocalEditorShared.applyButtonActiveState(markerVisibilityButton, markersVisible);
5541
- overlaySettingsButton.disabled = disabled;
5675
+ overlaySettingsButton.disabled = !isPreviewToolEnabled('spatial-overlay');
5542
5676
  setToolbarButtonTooltip(overlaySettingsButton, '视口信息层设置');
5543
5677
  LocalEditorShared.applyButtonActiveState(overlaySettingsButton, overlaySettingsOpen);
5544
5678
  const overlaySettings = viewportTools?.overlay;
5545
5679
  for (const [key, input] of overlayInputs) {
5546
- input.disabled = disabled;
5680
+ input.disabled = !isPreviewToolEnabled('spatial-overlay');
5547
5681
  input.checked = overlaySettings?.[key] ?? false;
5548
5682
  }
5549
5683
  measureButton.disabled = viewportControlsDisabled;
@@ -5559,27 +5693,33 @@ export function createLocalEditorBrowserUi(options = {}) {
5559
5693
  if (!inEditor || disabled || viewportToolsGroup.style.display === 'none')
5560
5694
  closeOverlaySettingsPopover();
5561
5695
  const gridState = state.grid ?? { visible: false, available: false };
5562
- performanceMonitorButton.style.display = inPrefabStage ? 'none' : 'inline-flex';
5563
- performanceMonitorButton.disabled = disabled || inPrefabStage;
5564
- setToolbarButtonTooltip(performanceMonitorButton, performanceMonitorOpen ? '隐藏性能监控' : '显示性能监控');
5696
+ performanceMonitorButton.style.display = isPreviewToolVisible('performance-monitor') ? 'inline-flex' : 'none';
5697
+ performanceMonitorButton.disabled = !isPreviewToolEnabled('performance-monitor');
5698
+ const performanceMonitorSupport = getPreviewToolSupport('performance-monitor');
5699
+ setToolbarButtonTooltip(performanceMonitorButton, performanceMonitorSupport.support === 'enabled'
5700
+ ? performanceMonitorOpen ? '隐藏性能监控' : '显示性能监控'
5701
+ : performanceMonitorSupport.reason);
5565
5702
  LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
5566
- prefabComparisonPreviewButton.style.display = inPrefabStage ? 'inline-flex' : 'none';
5567
- prefabComparisonPreviewButton.disabled = disabled || !inPrefabStage;
5568
- setToolbarButtonTooltip(prefabComparisonPreviewButton, prefabComparisonPreviewOpen
5569
- ? '隐藏对比预览 (Shift+P)'
5570
- : '显示对比预览 (Shift+P)');
5703
+ prefabComparisonPreviewButton.style.display = isPreviewToolVisible('prefab-comparison') ? 'inline-flex' : 'none';
5704
+ prefabComparisonPreviewButton.disabled = !isPreviewToolEnabled('prefab-comparison');
5705
+ const prefabComparisonSupport = getPreviewToolSupport('prefab-comparison');
5706
+ setToolbarButtonTooltip(prefabComparisonPreviewButton, prefabComparisonSupport.support === 'enabled'
5707
+ ? prefabComparisonPreviewOpen
5708
+ ? '隐藏对比预览 (Shift+P)'
5709
+ : '显示对比预览 (Shift+P)'
5710
+ : prefabComparisonSupport.reason);
5571
5711
  LocalEditorShared.applyButtonActiveState(prefabComparisonPreviewButton, inPrefabStage && prefabComparisonPreviewOpen);
5572
5712
  gridToggleButton.disabled = disabled || !gridState.available;
5573
5713
  setToolbarButtonTooltip(gridToggleButton, gridState.visible ? '隐藏 Scene View 网格' : '显示 Scene View 网格');
5574
5714
  LocalEditorShared.applyButtonActiveState(gridToggleButton, gridState.visible);
5575
- toolGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5576
- spaceGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5715
+ toolGroup.style.display = isPreviewToolVisible('select') ? 'flex' : 'none';
5716
+ spaceGroup.style.display = isPreviewToolVisible('transform-space') ? 'flex' : 'none';
5577
5717
  for (const [tool, button] of toolButtons) {
5578
- button.disabled = disabled;
5718
+ button.disabled = !isPreviewToolEnabled(tool);
5579
5719
  LocalEditorShared.applyButtonActiveState(button, transformTool?.activeTool === tool);
5580
5720
  }
5581
5721
  for (const [space, button] of Object.entries(spaceButtons)) {
5582
- button.disabled = disabled;
5722
+ button.disabled = !isPreviewToolEnabled('transform-space');
5583
5723
  LocalEditorShared.applyButtonActiveState(button, transformTool?.activeSpace === space);
5584
5724
  }
5585
5725
  sceneHelpButton.disabled = disabled;
@@ -5591,38 +5731,38 @@ export function createLocalEditorBrowserUi(options = {}) {
5591
5731
  canDistribute: false,
5592
5732
  };
5593
5733
  const operationSettings = transformOperations.settings;
5594
- snapGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5595
- snapButton.disabled = disabled;
5596
- snapEnabledInput.disabled = disabled;
5734
+ snapGroup.style.display = isPreviewToolVisible('snap') ? 'flex' : 'none';
5735
+ snapButton.disabled = !isPreviewToolEnabled('snap');
5736
+ snapEnabledInput.disabled = !isPreviewToolEnabled('snap');
5597
5737
  snapEnabledInput.checked = operationSettings.snap.enabled;
5598
5738
  LocalEditorShared.applyButtonActiveState(snapButton, operationSettings.snap.enabled || snapSettingsOpen);
5599
5739
  setToolbarButtonTooltip(snapButton, `吸附设置 · 位移 ${formatSnapStepInputValue(operationSettings.snap, 'move')} · 旋转 ${formatSnapStepInputValue(operationSettings.snap, 'rotate')}° · 缩放 ${formatSnapStepInputValue(operationSettings.snap, 'scale')}`);
5600
5740
  for (const [kind, input] of snapStepInputs) {
5601
- input.disabled = disabled;
5741
+ input.disabled = !isPreviewToolEnabled('snap');
5602
5742
  if (doc.activeElement !== input)
5603
5743
  input.value = formatSnapStepInputValue(operationSettings.snap, kind);
5604
5744
  }
5605
5745
  if (!inEditor || disabled || snapGroup.style.display === 'none')
5606
5746
  closeSnapSettingsPopover();
5607
- placementGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5608
- placementButton.disabled = disabled;
5747
+ placementGroup.style.display = isPreviewToolVisible('placement') ? 'flex' : 'none';
5748
+ placementButton.disabled = !isPreviewToolEnabled('placement');
5609
5749
  setToolbarButtonIcon(doc, placementButton, PLACEMENT_MODE_ICONS[operationSettings.placementMode]);
5610
5750
  setToolbarButtonTooltip(placementButton, `放置模式 · ${PLACEMENT_MODE_DESCRIPTIONS[operationSettings.placementMode]}`);
5611
5751
  LocalEditorShared.applyButtonActiveState(placementButton, operationSettings.placementMode !== 'off' || placementSettingsOpen);
5612
5752
  for (const [mode, button] of Object.entries(placementButtons)) {
5613
- button.disabled = disabled;
5753
+ button.disabled = !isPreviewToolEnabled('placement');
5614
5754
  LocalEditorShared.applyButtonActiveState(button, operationSettings.placementMode === mode);
5615
5755
  }
5616
5756
  if (!inEditor || disabled || placementGroup.style.display === 'none')
5617
5757
  closePlacementSettingsPopover();
5618
- actionGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
5758
+ actionGroup.style.display = isPreviewToolVisible('transform-actions') ? 'flex' : 'none';
5619
5759
  const hasTransformAction = transformOperations.canAlign || transformOperations.canDistribute;
5620
- transformActionButton.disabled = disabled || !hasTransformAction;
5760
+ transformActionButton.disabled = !isPreviewToolEnabled('transform-actions') || !hasTransformAction;
5621
5761
  setToolbarButtonTooltip(transformActionButton, hasTransformAction ? '对齐与分布' : '选择至少 2 个对象后可用');
5622
5762
  LocalEditorShared.applyButtonActiveState(transformActionButton, transformActionOpen);
5623
5763
  for (const [action, button] of transformActionButtons) {
5624
5764
  const enabled = isTransformActionEnabled(action, transformOperations);
5625
- button.disabled = disabled || !enabled;
5765
+ button.disabled = !isPreviewToolEnabled('transform-actions') || !enabled;
5626
5766
  button.style.opacity = button.disabled ? '0.45' : '1';
5627
5767
  button.style.cursor = button.disabled ? 'not-allowed' : 'pointer';
5628
5768
  }
@@ -5645,12 +5785,32 @@ export function createLocalEditorBrowserUi(options = {}) {
5645
5785
  inPrefabStage: true,
5646
5786
  activeRightTab,
5647
5787
  });
5788
+ const activeBottomTab = panelRegistry.getBottomDockTab();
5789
+ const assetBrowserTabChanged = assetBrowserTab !== lastRenderedAssetBrowserTab;
5790
+ const bottomDockTabChanged = activeBottomTab !== lastRenderedBottomDockTab;
5791
+ const selectedAssetChanged = state.selectedAssetId !== lastRenderedSelectedAssetId;
5792
+ const assetBrowserScrollSnapshot = activeBottomTab === 'assets'
5793
+ ? assetBrowserViewportReveal.captureScrollSnapshot()
5794
+ : { scrollTop: null };
5648
5795
  leftDockTabs.style.display = 'none';
5649
5796
  rightDockTabs.style.display = rightDockVisibility.tabsDisplay;
5650
5797
  inspectorPanel.style.display = rightDockVisibility.inspectorDisplay;
5651
5798
  renderingPanel.style.display = rightDockVisibility.renderingDisplay;
5652
- renderPrefabStageStructurePanel(prefabStage);
5799
+ hierarchyController.render(state);
5653
5800
  renderPrefabStagePropertiesPanel(prefabStage);
5801
+ LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab);
5802
+ if (activeBottomTab === 'assets' && !assetBrowserTabChanged && !bottomDockTabChanged) {
5803
+ assetBrowserViewportReveal.restoreScrollSnapshot(assetBrowserScrollSnapshot);
5804
+ }
5805
+ const suppressAssetScroll = state.selectedAssetId
5806
+ ? assetBrowserViewportReveal.consumeRevealSuppression(state.selectedAssetId, { clearWhenDifferent: selectedAssetChanged })
5807
+ : false;
5808
+ if (activeBottomTab === 'assets' && selectedAssetChanged && state.selectedAssetId && !suppressAssetScroll) {
5809
+ revealSelectedAssetBrowserItem(state.selectedAssetId);
5810
+ }
5811
+ lastRenderedAssetBrowserTab = assetBrowserTab;
5812
+ lastRenderedBottomDockTab = activeBottomTab;
5813
+ lastRenderedSelectedAssetId = state.selectedAssetId ?? null;
5654
5814
  restoreLocalEditorEditableFocus(doc, focusSnapshot);
5655
5815
  return;
5656
5816
  }