@fps-games/editor 0.1.4-beta.5 → 0.1.5-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 (249) hide show
  1. package/dist/build-info.json +16 -16
  2. package/dist/local-editor-harness.d.ts +24 -5
  3. package/dist/local-editor-harness.d.ts.map +1 -1
  4. package/dist/local-editor-harness.js +457 -91
  5. package/dist/local-editor-harness.js.map +1 -1
  6. package/dist/local-editor-performance-stats.d.ts +12 -0
  7. package/dist/local-editor-performance-stats.d.ts.map +1 -0
  8. package/dist/local-editor-performance-stats.js +46 -0
  9. package/dist/local-editor-performance-stats.js.map +1 -0
  10. package/dist/playable-babylon-facade.d.ts +2 -2
  11. package/dist/playable-babylon-facade.d.ts.map +1 -1
  12. package/dist/playable-babylon-facade.js +1 -1
  13. package/dist/playable-babylon-facade.js.map +1 -1
  14. package/dist/playable-babylon-rendering.d.ts +57 -12
  15. package/dist/playable-babylon-rendering.d.ts.map +1 -1
  16. package/dist/playable-babylon-rendering.js +529 -20
  17. package/dist/playable-babylon-rendering.js.map +1 -1
  18. package/dist/playable-local-editor-host.d.ts +10 -9
  19. package/dist/playable-local-editor-host.d.ts.map +1 -1
  20. package/dist/playable-local-editor-host.js.map +1 -1
  21. package/dist/playable-sdk.d.ts +5 -3
  22. package/dist/playable-sdk.d.ts.map +1 -1
  23. package/dist/playable-sdk.js +3 -2
  24. package/dist/playable-sdk.js.map +1 -1
  25. package/dist/static-shadow-cpu-worker.d.ts +7 -0
  26. package/dist/static-shadow-cpu-worker.d.ts.map +1 -0
  27. package/dist/static-shadow-cpu-worker.js +221 -0
  28. package/dist/static-shadow-cpu-worker.js.map +1 -0
  29. package/node_modules/@fps-games/babylon-renderer/dist/index.d.ts +3 -1
  30. package/node_modules/@fps-games/babylon-renderer/dist/index.d.ts.map +1 -1
  31. package/node_modules/@fps-games/babylon-renderer/dist/index.js +3 -1
  32. package/node_modules/@fps-games/babylon-renderer/dist/index.js.map +1 -1
  33. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.d.ts +4 -0
  34. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.d.ts.map +1 -0
  35. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js +584 -0
  36. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-artifact-system.js.map +1 -0
  37. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-atlas.d.ts +61 -0
  38. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-atlas.d.ts.map +1 -0
  39. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-atlas.js +382 -0
  40. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-atlas.js.map +1 -0
  41. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-bake.d.ts +47 -0
  42. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-bake.d.ts.map +1 -0
  43. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-bake.js +285 -0
  44. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-bake.js.map +1 -0
  45. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.d.ts +88 -0
  46. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.d.ts.map +1 -0
  47. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js +813 -0
  48. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-baker.js.map +1 -0
  49. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-rendering.d.ts +27 -0
  50. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-rendering.d.ts.map +1 -0
  51. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-rendering.js +220 -0
  52. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-rendering.js.map +1 -0
  53. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-system.d.ts +35 -3
  54. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-system.d.ts.map +1 -1
  55. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-system.js +65 -609
  56. package/node_modules/@fps-games/babylon-renderer/dist/shadows/static-projected-shadow-system.js.map +1 -1
  57. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts +169 -14
  58. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.d.ts.map +1 -1
  59. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js +9 -3
  60. package/node_modules/@fps-games/babylon-renderer/dist/shadows/types.js.map +1 -1
  61. package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
  62. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +2 -0
  63. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
  64. package/node_modules/@fps-games/editor-babylon/dist/index.js +2 -0
  65. package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
  66. package/node_modules/@fps-games/editor-babylon/dist/performance-monitor.d.ts +34 -0
  67. package/node_modules/@fps-games/editor-babylon/dist/performance-monitor.d.ts.map +1 -0
  68. package/node_modules/@fps-games/editor-babylon/dist/performance-monitor.js +272 -0
  69. package/node_modules/@fps-games/editor-babylon/dist/performance-monitor.js.map +1 -0
  70. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts +26 -0
  71. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts.map +1 -0
  72. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js +312 -0
  73. package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js.map +1 -0
  74. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.d.ts.map +1 -1
  75. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.js +51 -29
  76. package/node_modules/@fps-games/editor-babylon/dist/projection-selection-controller.js.map +1 -1
  77. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +6 -0
  78. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  79. package/node_modules/@fps-games/editor-babylon/dist/projection.js +69 -40
  80. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  81. package/node_modules/@fps-games/editor-babylon/dist/rendering.d.ts +19 -0
  82. package/node_modules/@fps-games/editor-babylon/dist/rendering.d.ts.map +1 -0
  83. package/node_modules/@fps-games/editor-babylon/dist/rendering.js +66 -0
  84. package/node_modules/@fps-games/editor-babylon/dist/rendering.js.map +1 -0
  85. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts +5 -2
  86. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts.map +1 -1
  87. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js +65 -32
  88. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js.map +1 -1
  89. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts.map +1 -1
  90. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js +19 -2
  91. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js.map +1 -1
  92. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  93. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +1 -1
  94. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  95. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  96. package/node_modules/@fps-games/editor-browser/dist/local-editor-rendering-actions.d.ts +8 -0
  97. package/node_modules/@fps-games/editor-browser/dist/local-editor-rendering-actions.d.ts.map +1 -0
  98. package/node_modules/@fps-games/editor-browser/dist/local-editor-rendering-actions.js +14 -0
  99. package/node_modules/@fps-games/editor-browser/dist/local-editor-rendering-actions.js.map +1 -0
  100. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts +5 -0
  101. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
  102. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +34 -1
  103. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
  104. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts +47 -0
  105. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +1 -0
  106. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +404 -0
  107. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -0
  108. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  109. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +59 -0
  110. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  111. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
  112. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +10 -2
  113. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +1 -1
  114. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  115. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  116. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +17 -0
  117. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  118. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts +1 -1
  119. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts.map +1 -1
  120. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js +12 -6
  121. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js.map +1 -1
  122. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  123. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +466 -42
  124. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  125. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +70 -5
  126. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  127. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +3 -1
  128. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  129. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +596 -5
  130. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  131. package/node_modules/@fps-games/editor-browser/package.json +3 -3
  132. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts +14 -1
  133. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts.map +1 -1
  134. package/node_modules/@fps-games/editor-core/dist/editor-session.js +34 -10
  135. package/node_modules/@fps-games/editor-core/dist/editor-session.js.map +1 -1
  136. package/node_modules/@fps-games/editor-core/dist/inspector.d.ts +2 -1
  137. package/node_modules/@fps-games/editor-core/dist/inspector.d.ts.map +1 -1
  138. package/node_modules/@fps-games/editor-core/dist/inspector.js +11 -1
  139. package/node_modules/@fps-games/editor-core/dist/inspector.js.map +1 -1
  140. package/node_modules/@fps-games/editor-core/dist/serialized-object.d.ts +7 -0
  141. package/node_modules/@fps-games/editor-core/dist/serialized-object.d.ts.map +1 -1
  142. package/node_modules/@fps-games/editor-core/dist/serialized-object.js +1 -0
  143. package/node_modules/@fps-games/editor-core/dist/serialized-object.js.map +1 -1
  144. package/node_modules/@fps-games/editor-core/package.json +2 -2
  145. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  146. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
  147. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +10 -5
  148. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
  149. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.d.ts.map +1 -1
  150. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js +3 -1
  151. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/placement.js.map +1 -1
  152. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +4 -1
  153. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
  154. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +29 -0
  155. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
  156. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +10 -0
  157. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
  158. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
  159. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +3 -0
  160. package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
  161. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +1 -0
  162. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  163. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +1 -0
  164. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  165. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts +33 -2
  166. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts.map +1 -1
  167. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js +232 -16
  168. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js.map +1 -1
  169. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts +1 -1
  170. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.d.ts.map +1 -1
  171. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js +1 -1
  172. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/index.js.map +1 -1
  173. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts +12 -1
  174. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
  175. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +153 -0
  176. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
  177. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/index.d.ts +4 -2
  178. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/index.d.ts.map +1 -1
  179. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/index.js +2 -1
  180. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/index.js.map +1 -1
  181. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.d.ts.map +1 -1
  182. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js +4 -1
  183. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js.map +1 -1
  184. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/rendering-alpha-index.d.ts +19 -0
  185. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/rendering-alpha-index.d.ts.map +1 -0
  186. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/rendering-alpha-index.js +57 -0
  187. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/rendering-alpha-index.js.map +1 -0
  188. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/types.d.ts +7 -1
  189. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/types.d.ts.map +1 -1
  190. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.d.ts.map +1 -1
  191. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +620 -36
  192. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
  193. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/profile.d.ts +8 -3
  194. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/profile.d.ts.map +1 -1
  195. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/profile.js +258 -10
  196. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/profile.js.map +1 -1
  197. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts +110 -3
  198. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts.map +1 -1
  199. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
  200. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +25 -0
  201. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
  202. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +2 -1
  203. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
  204. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.d.ts.map +1 -1
  205. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js +4 -0
  206. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js.map +1 -1
  207. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/companion-configs.d.ts +9 -1
  208. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/companion-configs.d.ts.map +1 -1
  209. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/companion-configs.js +12 -1
  210. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/companion-configs.js.map +1 -1
  211. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/types.d.ts +2 -0
  212. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/types.d.ts.map +1 -1
  213. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts +1 -0
  214. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
  215. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +75 -0
  216. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
  217. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/index.d.ts +1 -0
  218. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/index.d.ts.map +1 -1
  219. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/index.js +1 -0
  220. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/index.js.map +1 -1
  221. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts +17 -0
  222. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -0
  223. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +262 -0
  224. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -0
  225. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.d.ts.map +1 -1
  226. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js +7 -3
  227. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js.map +1 -1
  228. package/node_modules/@fps-games/editor-playable-sdk/dist/session/identity.d.ts +6 -0
  229. package/node_modules/@fps-games/editor-playable-sdk/dist/session/identity.d.ts.map +1 -1
  230. package/node_modules/@fps-games/editor-playable-sdk/dist/session/identity.js +31 -0
  231. package/node_modules/@fps-games/editor-playable-sdk/dist/session/identity.js.map +1 -1
  232. package/node_modules/@fps-games/editor-playable-sdk/dist/session/index.d.ts +2 -1
  233. package/node_modules/@fps-games/editor-playable-sdk/dist/session/index.d.ts.map +1 -1
  234. package/node_modules/@fps-games/editor-playable-sdk/dist/session/index.js +1 -1
  235. package/node_modules/@fps-games/editor-playable-sdk/dist/session/index.js.map +1 -1
  236. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.d.ts.map +1 -1
  237. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.js +21 -9
  238. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.js.map +1 -1
  239. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts +151 -0
  240. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.d.ts.map +1 -0
  241. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js +445 -0
  242. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/artifact.js.map +1 -0
  243. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/index.d.ts +2 -0
  244. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/index.d.ts.map +1 -0
  245. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/index.js +2 -0
  246. package/node_modules/@fps-games/editor-playable-sdk/dist/static-shadows/index.js.map +1 -0
  247. package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
  248. package/node_modules/@fps-games/editor-protocol/package.json +1 -1
  249. package/package.json +8 -8
@@ -10,16 +10,18 @@ export { createLocalEditorViewportRevealController, isLocalEditorElementVisibleI
10
10
  export { createLocalEditorHierarchyBlankMenu, createLocalEditorHierarchyCopyShortcutAction, createLocalEditorHierarchyDeleteShortcutAction, createLocalEditorHierarchyDuplicateShortcutAction, createLocalEditorHierarchyNodeMenu, createLocalEditorHierarchyPasteShortcutAction, createLocalEditorHierarchySelectAllShortcutAction, } from './local-editor-ui-hierarchy-actions.js';
11
11
  export { createLocalEditorHierarchyController, } from './local-editor-ui-hierarchy-controller.js';
12
12
  export { resolveLocalEditorHierarchySearchRows, } from './local-editor-ui-hierarchy-view.js';
13
+ export { createLocalEditorHierarchyAttachDialog, resolveLocalEditorHierarchyAttachTargets, } from './local-editor-ui-hierarchy-attach-dialog.js';
13
14
  export { canLocalEditorHierarchyNodeHaveChildren, createLocalEditorHierarchyTreeModel, isLocalEditorHierarchyNodeSelectable, isLocalEditorHierarchyNodeMovable, } from './local-editor-ui-hierarchy-tree.js';
14
15
  export { createLocalEditorContextMenuController, } from './local-editor-ui-context-menu.js';
15
16
  export { createLocalEditorTooltipController, } from './local-editor-ui-tooltip.js';
16
17
  import { createLocalEditorWorkbenchInputRouter } from './local-editor-ui-input-router.js';
17
18
  import { createLocalEditorPanelRegistry } from './local-editor-ui-panel-registry.js';
18
19
  import * as LocalEditorShared from './local-editor-ui-shared.js';
20
+ import { findLocalEditorRenderingAction } from './local-editor-rendering-actions.js';
19
21
  import { createShortcutHelpPanel as createLocalEditorShortcutHelpPanel } from './local-editor-ui-shortcuts.js';
20
22
  import { applyLocalEditorTheme, ensureLocalEditorTheme, LOCAL_EDITOR_THEME_CLASS, normalizeLocalEditorThemeName, } from './local-editor-ui-theme.js';
21
23
  import { createDefaultLocalEditorWorkbenchLayout, createLocalEditorWorkbenchLayoutController, createLocalEditorWorkbench, createSceneHeaderToolbar, createWorkbenchPanelContent, } from './local-editor-ui-workbench.js';
22
- import { createLocalEditorIcon } from './local-editor-ui-icons.js';
24
+ import { createLocalEditorIcon, isLocalEditorIconName } from './local-editor-ui-icons.js';
23
25
  export { applyLocalEditorBrowserInspectorControlBinding, createLocalEditorBrowserInspectorControlRegistry, formatLocalEditorBrowserInspectorNumberValue, formatLocalEditorBrowserInspectorValue, parseLocalEditorBrowserInspectorNumberValue, resolveLocalEditorBrowserInspectorSectionStatus, resolveLocalEditorBrowserInspectorControlRegistration, } from './local-editor-ui-panels.js';
24
26
  export { createLocalEditorBrowserInspectorGroupValueClipboardPayload, createLocalEditorBrowserInspectorVectorCopyPayload, parseLocalEditorBrowserInspectorGroupValueClipboardPayload, } from './local-editor-inspector-clipboard.js';
25
27
  export { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, isLocalEditorBrowserInspectorTransformVectorGroupPath, resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromProperties, } from './local-editor-inspector-groups.js';
@@ -108,6 +110,7 @@ const VIEWPORT_PROJECTION_LABELS = {
108
110
  perspective: '透视',
109
111
  orthographic: '正交',
110
112
  };
113
+ const STATIC_SHADOW_BAKE_ACTION_ID = 'bake-static-shadows';
111
114
  const TRANSFORM_ACTION_GROUPS = [
112
115
  {
113
116
  title: '对齐到 Active Object',
@@ -336,6 +339,32 @@ function createRenderingPropertyInput(input, source) {
336
339
  source,
337
340
  };
338
341
  }
342
+ function createRenderingActionInput(button) {
343
+ const actionId = button.dataset.editorRenderingAction;
344
+ if (!actionId)
345
+ return null;
346
+ const params = parseRenderingActionParams(button.dataset.renderingActionParams);
347
+ return {
348
+ actionId,
349
+ sectionId: button.dataset.renderingSectionId,
350
+ systemId: button.dataset.renderingSystemId,
351
+ path: button.dataset.renderingPath,
352
+ ...(params ? { params } : {}),
353
+ };
354
+ }
355
+ function parseRenderingActionParams(value) {
356
+ if (!value)
357
+ return null;
358
+ try {
359
+ const parsed = JSON.parse(value);
360
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
361
+ ? parsed
362
+ : null;
363
+ }
364
+ catch {
365
+ return null;
366
+ }
367
+ }
339
368
  function readInspectorCommitMode(input) {
340
369
  return input.dataset.serializedCommitMode ?? 'live';
341
370
  }
@@ -596,6 +625,145 @@ function cssEscape(value) {
596
625
  ? CSS.escape(value)
597
626
  : value.replace(/["\\]/g, '\\$&');
598
627
  }
628
+ const PERFORMANCE_MONITOR_METRIC_GROUPS = [
629
+ {
630
+ title: null,
631
+ metrics: [
632
+ {
633
+ key: 'fps',
634
+ label: 'FPS',
635
+ description: '每秒渲染帧数。打开性能浮窗时会启用连续渲染,所以这里显示实时值。',
636
+ format: stats => formatPerformanceInteger(stats?.fps ?? null),
637
+ },
638
+ {
639
+ key: 'frame',
640
+ label: 'Frame',
641
+ description: '最近一帧耗时,单位毫秒。16.7ms 约等于 60 FPS。',
642
+ format: stats => formatPerformanceFrameMs(stats?.frameMs ?? null),
643
+ },
644
+ {
645
+ key: 'drawCalls',
646
+ label: 'Draw calls',
647
+ description: 'Babylon 当前帧提交的绘制调用数量。它受材质、mesh、阴影、辅助层和合批状态影响。',
648
+ format: stats => formatPerformanceInteger(stats?.drawCalls ?? null),
649
+ },
650
+ {
651
+ key: 'objects',
652
+ label: 'Objects',
653
+ description: '编辑器层级中的 authored 对象数量,不包含 root 行,不等同于 Babylon mesh 数。',
654
+ format: stats => formatPerformanceInteger(stats?.objectCount ?? null),
655
+ },
656
+ {
657
+ key: 'meshes',
658
+ label: 'Meshes',
659
+ description: 'Babylon scene.meshes 总数,包含资产 mesh、primitive、阴影预览和编辑器辅助 mesh。',
660
+ format: stats => formatPerformanceInteger(stats?.meshCount ?? null),
661
+ },
662
+ {
663
+ key: 'activeMeshes',
664
+ label: 'Active meshes',
665
+ description: '当前相机和裁剪结果下参与本帧 active mesh 评估的 mesh 数。',
666
+ format: stats => formatPerformanceInteger(stats?.activeMeshCount ?? null),
667
+ },
668
+ {
669
+ key: 'materials',
670
+ label: 'Materials',
671
+ description: 'Babylon scene.materials 数量。材质越分散,越难形成低 draw call。',
672
+ format: stats => formatPerformanceInteger(stats?.materialCount ?? null),
673
+ },
674
+ {
675
+ key: 'textures',
676
+ label: 'Textures',
677
+ description: 'Babylon scene.textures 数量,包含材质贴图和部分 runtime 生成纹理。',
678
+ format: stats => formatPerformanceInteger(stats?.textureCount ?? null),
679
+ },
680
+ {
681
+ key: 'lights',
682
+ label: 'Lights',
683
+ description: 'Babylon scene.lights 数量。',
684
+ format: stats => formatPerformanceInteger(stats?.lightCount ?? null),
685
+ },
686
+ {
687
+ key: 'cameras',
688
+ label: 'Cameras',
689
+ description: 'Babylon scene.cameras 数量。',
690
+ format: stats => formatPerformanceInteger(stats?.cameraCount ?? null),
691
+ },
692
+ ],
693
+ },
694
+ {
695
+ title: 'Mesh 类别 · active/total',
696
+ description: '按 Babylon mesh class 统计,值格式为 active/total。',
697
+ metrics: [
698
+ {
699
+ key: 'meshClassMesh',
700
+ label: 'Mesh',
701
+ description: '普通 Mesh:独立几何网格,通常会独立参与一次渲染批次判断。',
702
+ format: stats => formatPerformanceClassBreakdown(stats, 'mesh'),
703
+ },
704
+ {
705
+ key: 'meshClassInstancedMesh',
706
+ label: 'Instance',
707
+ description: 'InstancedMesh:共享 source mesh 的实例,但仍会进入 active mesh 统计。',
708
+ format: stats => formatPerformanceClassBreakdown(stats, 'instancedMesh'),
709
+ },
710
+ {
711
+ key: 'meshClassLinesMesh',
712
+ label: 'Lines',
713
+ description: 'LinesMesh:线框/辅助线 mesh,常见于相机视锥、灯光方向、编辑器辅助显示。',
714
+ format: stats => formatPerformanceClassBreakdown(stats, 'linesMesh'),
715
+ },
716
+ {
717
+ key: 'meshClassGroundMesh',
718
+ label: 'Ground',
719
+ description: 'GroundMesh:Babylon ground 类型 mesh,常用于地面或平面。',
720
+ format: stats => formatPerformanceClassBreakdown(stats, 'groundMesh'),
721
+ },
722
+ {
723
+ key: 'meshClassOther',
724
+ label: 'Other',
725
+ description: '其他 Babylon mesh 子类,表示未归入 Mesh/Instance/Lines/Ground 的类型。',
726
+ format: stats => formatPerformanceClassBreakdown(stats, 'other'),
727
+ },
728
+ ],
729
+ },
730
+ {
731
+ title: '来源 · active/total',
732
+ description: '按编辑器 runtime 来源粗分类,值格式为 active/total。',
733
+ metrics: [
734
+ {
735
+ key: 'meshCategoryAssetMesh',
736
+ label: 'Asset',
737
+ description: '资产 Mesh:由 GLB/模型资产实例化或克隆出来的可渲染子 mesh。',
738
+ format: stats => formatPerformanceCategoryBreakdown(stats, 'assetMesh'),
739
+ },
740
+ {
741
+ key: 'meshCategoryPrimitiveMesh',
742
+ label: 'Primitive',
743
+ description: 'Primitive Mesh:编辑器基础体生成的 mesh,例如 Cube、Sphere、Capsule、Plane。',
744
+ format: stats => formatPerformanceCategoryBreakdown(stats, 'primitiveMesh'),
745
+ },
746
+ {
747
+ key: 'meshCategoryStaticProjectedShadow',
748
+ label: 'Shadow',
749
+ description: '静态投影阴影预览 mesh。数量高时通常会显著抬高 draw calls。',
750
+ format: stats => formatPerformanceCategoryBreakdown(stats, 'staticProjectedShadow'),
751
+ },
752
+ {
753
+ key: 'meshCategoryEditorHelper',
754
+ label: 'Helper',
755
+ description: '编辑器辅助 mesh,例如网格、天空、相机/灯光 helper、gizmo 辅助显示。',
756
+ format: stats => formatPerformanceCategoryBreakdown(stats, 'editorHelper'),
757
+ },
758
+ {
759
+ key: 'meshCategoryUncategorized',
760
+ label: 'Other',
761
+ description: '未能归入资产、基础体、阴影预览或编辑器辅助层的 mesh。',
762
+ format: stats => formatPerformanceCategoryBreakdown(stats, 'uncategorized'),
763
+ },
764
+ ],
765
+ },
766
+ ];
599
767
  function createSceneFrameRateOverlay(doc) {
600
768
  const root = doc.createElement('div');
601
769
  root.classList.add(LOCAL_EDITOR_THEME_CLASS);
@@ -686,6 +854,154 @@ function renderSceneFrameRateOverlay(overlay, stats) {
686
854
  stats.activeReasons.length ? `active: ${stats.activeReasons.join(', ')}` : '',
687
855
  ].filter(Boolean).join(' | ');
688
856
  }
857
+ function createPerformanceMonitorOverlay(doc) {
858
+ const root = doc.createElement('section');
859
+ root.classList.add(LOCAL_EDITOR_THEME_CLASS);
860
+ root.dataset.editorPerformanceMonitorOverlay = 'true';
861
+ root.setAttribute('aria-label', '编辑器性能监控');
862
+ root.style.cssText = [
863
+ 'position:absolute',
864
+ 'right:14px',
865
+ 'top:48px',
866
+ 'z-index:4',
867
+ 'display:none',
868
+ 'width:226px',
869
+ 'box-sizing:border-box',
870
+ 'padding:10px',
871
+ 'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
872
+ 'border-radius:6px',
873
+ 'background:color-mix(in srgb, var(--fps-editor-chrome) 88%, transparent)',
874
+ 'box-shadow:var(--fps-editor-shadow-panel)',
875
+ 'backdrop-filter:blur(6px)',
876
+ 'font-family:var(--fps-editor-font)',
877
+ 'font-size:11px',
878
+ 'font-weight:800',
879
+ 'color:var(--fps-editor-text)',
880
+ 'pointer-events:auto',
881
+ 'max-height:calc(100% - 64px)',
882
+ 'overflow:auto',
883
+ ].join(';');
884
+ const header = doc.createElement('div');
885
+ header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;';
886
+ const title = doc.createElement('div');
887
+ title.textContent = 'Performance';
888
+ title.style.cssText = 'min-width:0;color:var(--fps-editor-text-strong);font-size:12px;font-weight:900;line-height:1.2;';
889
+ const modeLabel = doc.createElement('span');
890
+ modeLabel.textContent = 'IDLE';
891
+ modeLabel.style.cssText = [
892
+ 'flex:0 0 auto',
893
+ 'padding:2px 5px',
894
+ 'border:1px solid var(--fps-editor-border-soft)',
895
+ 'border-radius:4px',
896
+ 'background:color-mix(in srgb, var(--fps-editor-field) 72%, transparent)',
897
+ 'color:var(--fps-editor-muted)',
898
+ 'font-size:9px',
899
+ 'line-height:1',
900
+ 'font-weight:900',
901
+ ].join(';');
902
+ header.append(title, modeLabel);
903
+ const grid = doc.createElement('div');
904
+ grid.style.cssText = [
905
+ 'display:grid',
906
+ 'grid-template-columns:minmax(0,1fr) minmax(48px,auto)',
907
+ 'gap:5px 10px',
908
+ 'align-items:center',
909
+ ].join(';');
910
+ const values = {};
911
+ for (const group of PERFORMANCE_MONITOR_METRIC_GROUPS) {
912
+ if (group.title) {
913
+ const groupTitle = doc.createElement('div');
914
+ groupTitle.textContent = group.title;
915
+ groupTitle.title = group.description ?? group.title;
916
+ groupTitle.setAttribute('aria-label', group.description ?? group.title);
917
+ groupTitle.style.cssText = [
918
+ 'grid-column:1/-1',
919
+ 'margin-top:3px',
920
+ 'padding-top:6px',
921
+ 'border-top:1px solid color-mix(in srgb, var(--fps-editor-border-soft) 72%, transparent)',
922
+ 'color:var(--fps-editor-text-strong)',
923
+ 'font-size:10px',
924
+ 'font-weight:900',
925
+ 'line-height:1',
926
+ 'cursor:help',
927
+ ].join(';');
928
+ grid.appendChild(groupTitle);
929
+ }
930
+ for (const metric of group.metrics) {
931
+ const rowLabel = doc.createElement('span');
932
+ rowLabel.textContent = metric.label;
933
+ rowLabel.title = metric.description;
934
+ rowLabel.setAttribute('aria-label', `${metric.label}: ${metric.description}`);
935
+ rowLabel.style.cssText = [
936
+ 'min-width:0',
937
+ 'overflow:hidden',
938
+ 'text-overflow:ellipsis',
939
+ 'white-space:nowrap',
940
+ 'color:var(--fps-editor-muted-strong)',
941
+ 'cursor:help',
942
+ ].join(';');
943
+ const value = doc.createElement('span');
944
+ value.textContent = '--';
945
+ value.title = metric.description;
946
+ value.setAttribute('aria-label', `${metric.label}: --。${metric.description}`);
947
+ value.style.cssText = [
948
+ 'min-width:48px',
949
+ 'justify-self:end',
950
+ 'font-variant-numeric:tabular-nums',
951
+ 'color:var(--fps-editor-text-strong)',
952
+ 'text-align:right',
953
+ 'cursor:help',
954
+ ].join(';');
955
+ values[metric.key] = value;
956
+ grid.append(rowLabel, value);
957
+ }
958
+ }
959
+ root.append(header, grid);
960
+ return { root, modeLabel, values };
961
+ }
962
+ function renderPerformanceMonitorOverlay(overlay, stats, open) {
963
+ if (!open) {
964
+ overlay.root.style.display = 'none';
965
+ return;
966
+ }
967
+ overlay.root.style.display = 'block';
968
+ overlay.modeLabel.textContent = stats?.mode === 'continuous' ? 'LIVE' : 'IDLE';
969
+ overlay.modeLabel.style.color = stats?.mode === 'continuous'
970
+ ? 'var(--fps-editor-success)'
971
+ : 'var(--fps-editor-muted)';
972
+ for (const group of PERFORMANCE_MONITOR_METRIC_GROUPS) {
973
+ for (const metric of group.metrics) {
974
+ const value = metric.format(stats);
975
+ overlay.values[metric.key].textContent = value;
976
+ overlay.values[metric.key].setAttribute('aria-label', `${metric.label}: ${value}。${metric.description}`);
977
+ }
978
+ }
979
+ overlay.root.title = [
980
+ '悬停各项查看中文解释',
981
+ stats ? `mode: ${stats.mode}` : 'mode: unknown',
982
+ stats?.activeReasons.length ? `active: ${stats.activeReasons.join(', ')}` : '',
983
+ ].filter(Boolean).join(' | ');
984
+ }
985
+ function formatPerformanceInteger(value) {
986
+ return typeof value === 'number' && Number.isFinite(value) ? String(Math.round(value)) : '--';
987
+ }
988
+ function formatPerformanceFrameMs(value) {
989
+ return typeof value === 'number' && Number.isFinite(value) ? `${value.toFixed(1)}ms` : '--';
990
+ }
991
+ function formatPerformanceClassBreakdown(stats, key) {
992
+ return formatPerformanceActiveTotal(stats?.activeMeshClassCounts?.[key] ?? null, stats?.meshClassCounts?.[key] ?? null);
993
+ }
994
+ function formatPerformanceCategoryBreakdown(stats, key) {
995
+ return formatPerformanceActiveTotal(stats?.activeMeshCategoryCounts?.[key] ?? null, stats?.meshCategoryCounts?.[key] ?? null);
996
+ }
997
+ function formatPerformanceActiveTotal(active, total) {
998
+ if (!isFinitePerformanceNumber(active) || !isFinitePerformanceNumber(total))
999
+ return '--';
1000
+ return `${Math.round(active)}/${Math.round(total)}`;
1001
+ }
1002
+ function isFinitePerformanceNumber(value) {
1003
+ return typeof value === 'number' && Number.isFinite(value);
1004
+ }
689
1005
  function createCoordinateAxesOverlay(doc) {
690
1006
  const root = doc.createElement('div');
691
1007
  root.dataset.editorCoordinateAxesOverlay = 'true';
@@ -1438,6 +1754,7 @@ export function createLocalEditorBrowserUi(options = {}) {
1438
1754
  const undoButton = createToolbarIconButton(doc, '撤销', 'undo', '撤销');
1439
1755
  const redoButton = createToolbarIconButton(doc, '重做', 'redo', '重做');
1440
1756
  let helpOpen = false;
1757
+ let performanceMonitorOpen = false;
1441
1758
  let assetPreviewOpen = false;
1442
1759
  let previewedAsset = null;
1443
1760
  let assetPreviewMode = 'preview';
@@ -1734,8 +2051,105 @@ export function createLocalEditorBrowserUi(options = {}) {
1734
2051
  transformActionPopover.appendChild(section);
1735
2052
  }
1736
2053
  actionGroup.appendChild(transformActionButton);
2054
+ const staticShadowBakeGroup = doc.createElement('div');
2055
+ staticShadowBakeGroup.style.cssText = [
2056
+ 'display:none',
2057
+ 'align-items:center',
2058
+ 'gap:4px',
2059
+ 'padding-left:8px',
2060
+ 'border-left:1px solid var(--fps-editor-divider)',
2061
+ ].join(';');
2062
+ const staticShadowBakeButton = createToolbarIconButton(doc, '烘焙静态阴影', 'save', '烘焙静态阴影');
2063
+ staticShadowBakeButton.dataset.editorToolbarStaticShadowBake = 'true';
2064
+ staticShadowBakeButton.dataset.editorRenderingAction = STATIC_SHADOW_BAKE_ACTION_ID;
2065
+ staticShadowBakeGroup.appendChild(staticShadowBakeButton);
2066
+ const staticShadowBakePopover = doc.createElement('div');
2067
+ staticShadowBakePopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
2068
+ staticShadowBakePopover.dataset.editorToolbarStaticShadowBakePopover = 'true';
2069
+ staticShadowBakePopover.setAttribute('role', 'dialog');
2070
+ staticShadowBakePopover.setAttribute('aria-label', '静态阴影烘焙进度');
2071
+ staticShadowBakePopover.style.cssText = [
2072
+ 'position:fixed',
2073
+ 'z-index:2147483641',
2074
+ 'display:none',
2075
+ 'flex-direction:column',
2076
+ 'gap:9px',
2077
+ 'width:360px',
2078
+ 'max-width:calc(100vw - 16px)',
2079
+ 'padding:10px',
2080
+ 'border:1px solid var(--fps-editor-border)',
2081
+ 'border-radius:3px',
2082
+ 'background:var(--fps-editor-panel)',
2083
+ 'box-shadow:var(--fps-editor-shadow-popover)',
2084
+ 'font-family:var(--fps-editor-font)',
2085
+ 'color:var(--fps-editor-text)',
2086
+ 'font-size:12px',
2087
+ 'pointer-events:auto',
2088
+ ].join(';');
2089
+ const staticShadowBakePopoverHeader = doc.createElement('div');
2090
+ staticShadowBakePopoverHeader.style.cssText = [
2091
+ 'display:flex',
2092
+ 'align-items:center',
2093
+ 'justify-content:space-between',
2094
+ 'gap:8px',
2095
+ ].join(';');
2096
+ const staticShadowBakePopoverTitle = doc.createElement('div');
2097
+ staticShadowBakePopoverTitle.textContent = '静态阴影烘焙';
2098
+ staticShadowBakePopoverTitle.style.cssText = [
2099
+ 'min-width:0',
2100
+ 'overflow:hidden',
2101
+ 'text-overflow:ellipsis',
2102
+ 'white-space:nowrap',
2103
+ 'font-size:12px',
2104
+ 'font-weight:900',
2105
+ 'color:var(--fps-editor-text-strong)',
2106
+ ].join(';');
2107
+ const staticShadowBakePopoverClose = createToolbarIconButton(doc, '关闭', 'discard', '关闭烘焙信息');
2108
+ staticShadowBakePopoverClose.dataset.editorToolbarStaticShadowBakePopoverClose = 'true';
2109
+ staticShadowBakePopoverHeader.appendChild(staticShadowBakePopoverTitle);
2110
+ staticShadowBakePopoverHeader.appendChild(staticShadowBakePopoverClose);
2111
+ const staticShadowBakePopoverStatus = doc.createElement('div');
2112
+ staticShadowBakePopoverStatus.dataset.editorToolbarStaticShadowBakePopoverStatus = 'true';
2113
+ staticShadowBakePopoverStatus.style.cssText = [
2114
+ 'color:var(--fps-editor-muted-strong)',
2115
+ 'font-size:11px',
2116
+ 'font-weight:800',
2117
+ 'line-height:1.35',
2118
+ 'overflow-wrap:anywhere',
2119
+ ].join(';');
2120
+ const staticShadowBakeProgress = doc.createElement('div');
2121
+ staticShadowBakeProgress.dataset.editorToolbarStaticShadowBakePopoverProgress = 'true';
2122
+ staticShadowBakeProgress.style.cssText = [
2123
+ 'height:8px',
2124
+ 'overflow:hidden',
2125
+ 'border:1px solid var(--fps-editor-border)',
2126
+ 'border-radius:3px',
2127
+ 'background:var(--fps-editor-chrome-dark)',
2128
+ ].join(';');
2129
+ const staticShadowBakeProgressFill = doc.createElement('div');
2130
+ staticShadowBakeProgressFill.style.cssText = [
2131
+ 'height:100%',
2132
+ 'width:0%',
2133
+ 'border-radius:2px',
2134
+ 'background:var(--fps-editor-accent-strong)',
2135
+ 'transition:width 140ms ease',
2136
+ ].join(';');
2137
+ staticShadowBakeProgress.appendChild(staticShadowBakeProgressFill);
2138
+ const staticShadowBakeDetails = doc.createElement('div');
2139
+ staticShadowBakeDetails.dataset.editorToolbarStaticShadowBakePopoverDetails = 'true';
2140
+ staticShadowBakeDetails.style.cssText = [
2141
+ 'display:grid',
2142
+ 'grid-template-columns:repeat(2, minmax(0, 1fr))',
2143
+ 'gap:6px',
2144
+ ].join(';');
2145
+ staticShadowBakePopover.appendChild(staticShadowBakePopoverHeader);
2146
+ staticShadowBakePopover.appendChild(staticShadowBakePopoverStatus);
2147
+ staticShadowBakePopover.appendChild(staticShadowBakeProgress);
2148
+ staticShadowBakePopover.appendChild(staticShadowBakeDetails);
1737
2149
  const themeToggleButton = createToolbarIconButton(doc, '主题', 'theme', '切换主题');
1738
2150
  themeToggleButton.dataset.editorThemeToggle = 'true';
2151
+ const performanceMonitorButton = createToolbarIconButton(doc, '性能监控', 'performance', '性能监控', 'toggle');
2152
+ performanceMonitorButton.dataset.performanceMonitorToggle = 'true';
1739
2153
  const gridToggleButton = createToolbarIconButton(doc, '网格', 'grid', '显示 / 隐藏 Scene View 网格');
1740
2154
  gridToggleButton.dataset.editorGridToggle = 'true';
1741
2155
  const sceneHelpButton = createToolbarIconButton(doc, '快捷键', 'help', '快捷键与操作说明');
@@ -1743,6 +2157,7 @@ export function createLocalEditorBrowserUi(options = {}) {
1743
2157
  sceneQuickActions.appendChild(undoButton);
1744
2158
  sceneQuickActions.appendChild(redoButton);
1745
2159
  sceneQuickActions.appendChild(dirtyBadge);
2160
+ sceneUtilityActions.appendChild(performanceMonitorButton);
1746
2161
  sceneUtilityActions.appendChild(gridToggleButton);
1747
2162
  sceneUtilityActions.appendChild(themeToggleButton);
1748
2163
  sceneUtilityActions.appendChild(sceneHelpButton);
@@ -1850,6 +2265,7 @@ export function createLocalEditorBrowserUi(options = {}) {
1850
2265
  ].join(';');
1851
2266
  const coordinateAxesOverlay = createCoordinateAxesOverlay(doc);
1852
2267
  const sceneFrameRateOverlay = createSceneFrameRateOverlay(doc);
2268
+ const performanceMonitorOverlay = createPerformanceMonitorOverlay(doc);
1853
2269
  const spatialOverlay = createSpatialOverlay(doc);
1854
2270
  const measurementOverlay = createMeasurementOverlay(doc);
1855
2271
  sceneToolOverlay.appendChild(sceneTitle);
@@ -1859,6 +2275,7 @@ export function createLocalEditorBrowserUi(options = {}) {
1859
2275
  sceneToolOverlay.appendChild(snapGroup);
1860
2276
  sceneToolOverlay.appendChild(placementGroup);
1861
2277
  sceneToolOverlay.appendChild(actionGroup);
2278
+ sceneToolOverlay.appendChild(staticShadowBakeGroup);
1862
2279
  sceneToolOverlay.appendChild(viewportToolsGroup);
1863
2280
  sceneToolOverlay.appendChild(sceneUtilityActions);
1864
2281
  sceneToolOverlay.appendChild(cameraPreviewGroup);
@@ -1868,15 +2285,18 @@ export function createLocalEditorBrowserUi(options = {}) {
1868
2285
  workbench.sceneFrame.appendChild(spatialOverlay.root);
1869
2286
  workbench.sceneFrame.appendChild(measurementOverlay.root);
1870
2287
  workbench.sceneFrame.appendChild(sceneFrameRateOverlay.root);
2288
+ workbench.sceneFrame.appendChild(performanceMonitorOverlay.root);
1871
2289
  workbench.sceneFrame.appendChild(coordinateAxesOverlay.root);
1872
2290
  root.appendChild(localTestMenu);
1873
2291
  root.appendChild(toolbarOverflowMenu);
2292
+ root.appendChild(staticShadowBakePopover);
1874
2293
  root.appendChild(snapSettingsPopover);
1875
2294
  root.appendChild(placementSettingsPopover);
1876
2295
  root.appendChild(transformActionPopover);
1877
2296
  root.appendChild(overlaySettingsPopover);
1878
2297
  tooltipSurfaces.add(localTestMenu);
1879
2298
  tooltipSurfaces.add(toolbarOverflowMenu);
2299
+ tooltipSurfaces.add(staticShadowBakePopover);
1880
2300
  tooltipSurfaces.add(snapSettingsPopover);
1881
2301
  tooltipSurfaces.add(placementSettingsPopover);
1882
2302
  tooltipSurfaces.add(transformActionPopover);
@@ -2062,12 +2482,14 @@ export function createLocalEditorBrowserUi(options = {}) {
2062
2482
  applyLocalEditorTheme(spatialOverlay.root, activeTheme);
2063
2483
  applyLocalEditorTheme(measurementOverlay.root, activeTheme);
2064
2484
  applyLocalEditorTheme(sceneFrameRateOverlay.root, activeTheme);
2485
+ applyLocalEditorTheme(performanceMonitorOverlay.root, activeTheme);
2065
2486
  applyLocalEditorTheme(shortcutHelpPanel, activeTheme);
2066
2487
  applyLocalEditorTheme(assetPreviewModal, activeTheme);
2067
2488
  applyLocalEditorTheme(assetPickerModal, activeTheme);
2068
2489
  applyLocalEditorTheme(boxSelectionOverlay, activeTheme);
2069
2490
  applyLocalEditorTheme(localTestMenu, activeTheme);
2070
2491
  applyLocalEditorTheme(toolbarOverflowMenu, activeTheme);
2492
+ applyLocalEditorTheme(staticShadowBakePopover, activeTheme);
2071
2493
  applyLocalEditorTheme(snapSettingsPopover, activeTheme);
2072
2494
  applyLocalEditorTheme(placementSettingsPopover, activeTheme);
2073
2495
  applyLocalEditorTheme(transformActionPopover, activeTheme);
@@ -2274,6 +2696,7 @@ export function createLocalEditorBrowserUi(options = {}) {
2274
2696
  snapGroup,
2275
2697
  placementGroup,
2276
2698
  actionGroup,
2699
+ staticShadowBakeGroup,
2277
2700
  viewportToolsGroup,
2278
2701
  sceneUtilityActions,
2279
2702
  cameraPreviewGroup,
@@ -2289,9 +2712,11 @@ export function createLocalEditorBrowserUi(options = {}) {
2289
2712
  { id: 'placement', element: placementGroup, kind: 'group' },
2290
2713
  { id: 'snap', element: snapGroup, kind: 'group' },
2291
2714
  { id: 'space', element: spaceGroup, kind: 'group' },
2715
+ { id: 'static-shadow-bake', element: staticShadowBakeGroup, kind: 'group' },
2292
2716
  ];
2293
2717
  let toolbarOverflowOpen = false;
2294
2718
  let toolbarOverflowRaf = null;
2719
+ let staticShadowBakePopoverOpen = false;
2295
2720
  function restoreToolbarOverflowItemStyle(item) {
2296
2721
  const original = toolbarOverflowOriginalStyles.get(item.element);
2297
2722
  if (!original)
@@ -2356,6 +2781,94 @@ export function createLocalEditorBrowserUi(options = {}) {
2356
2781
  toolbarOverflowMenu.style.display = 'none';
2357
2782
  LocalEditorShared.applyButtonActiveState(toolbarOverflowButton, false);
2358
2783
  }
2784
+ function closeStaticShadowBakePopover() {
2785
+ staticShadowBakePopoverOpen = false;
2786
+ staticShadowBakePopover.style.display = 'none';
2787
+ }
2788
+ function openStaticShadowBakePopover() {
2789
+ staticShadowBakePopoverOpen = true;
2790
+ renderStaticShadowBakePopover(currentState);
2791
+ }
2792
+ function positionStaticShadowBakePopover() {
2793
+ const rect = staticShadowBakeButton.getBoundingClientRect();
2794
+ const win = doc.defaultView;
2795
+ const viewportWidth = win?.innerWidth ?? doc.documentElement.clientWidth;
2796
+ const width = Math.min(360, Math.max(240, viewportWidth - 16));
2797
+ const left = Math.min(Math.max(8, rect.left + rect.width * 0.5 - width * 0.5), Math.max(8, viewportWidth - width - 8));
2798
+ staticShadowBakePopover.style.width = `${width}px`;
2799
+ staticShadowBakePopover.style.left = `${left}px`;
2800
+ staticShadowBakePopover.style.top = `${Math.max(38, rect.bottom + 6)}px`;
2801
+ }
2802
+ function renderStaticShadowBakePopover(state) {
2803
+ if (!staticShadowBakePopoverOpen || !state || state.mode !== 'editor') {
2804
+ staticShadowBakePopover.style.display = 'none';
2805
+ return;
2806
+ }
2807
+ const match = findLocalEditorRenderingAction(state.renderingPanel, STATIC_SHADOW_BAKE_ACTION_ID);
2808
+ if (!match) {
2809
+ staticShadowBakePopover.style.display = 'none';
2810
+ return;
2811
+ }
2812
+ positionStaticShadowBakePopover();
2813
+ staticShadowBakePopover.style.display = 'flex';
2814
+ staticShadowBakePopoverTitle.textContent = match.system?.label ?? match.action.label ?? '静态阴影烘焙';
2815
+ const progress = match.system?.progress;
2816
+ const status = match.system?.status || progress?.label || match.action.tooltip || '准备烘焙静态阴影...';
2817
+ staticShadowBakePopoverStatus.textContent = status;
2818
+ if (progress) {
2819
+ staticShadowBakeProgress.style.display = 'block';
2820
+ const value = typeof progress.value === 'number' && Number.isFinite(progress.value)
2821
+ ? Math.max(0, Math.min(1, progress.value))
2822
+ : progress.indeterminate
2823
+ ? 1
2824
+ : 0;
2825
+ staticShadowBakeProgressFill.style.width = `${Math.round(value * 100)}%`;
2826
+ staticShadowBakeProgressFill.style.opacity = progress.indeterminate ? '0.55' : '1';
2827
+ }
2828
+ else {
2829
+ staticShadowBakeProgress.style.display = 'none';
2830
+ staticShadowBakeProgressFill.style.width = '0%';
2831
+ staticShadowBakeProgressFill.style.opacity = '1';
2832
+ }
2833
+ LocalEditorShared.clearElement(staticShadowBakeDetails);
2834
+ const details = match.system?.details ?? [];
2835
+ staticShadowBakeDetails.style.display = details.length > 0 ? 'grid' : 'none';
2836
+ for (const detail of details) {
2837
+ const item = doc.createElement('div');
2838
+ item.style.cssText = [
2839
+ 'min-width:0',
2840
+ 'padding:6px',
2841
+ 'border:1px solid var(--fps-editor-border)',
2842
+ 'border-radius:3px',
2843
+ 'background:var(--fps-editor-chrome)',
2844
+ ].join(';');
2845
+ const label = doc.createElement('div');
2846
+ label.textContent = detail.label;
2847
+ label.style.cssText = [
2848
+ 'color:var(--fps-editor-muted)',
2849
+ 'font-size:10px',
2850
+ 'font-weight:800',
2851
+ 'line-height:1.25',
2852
+ 'overflow:hidden',
2853
+ 'text-overflow:ellipsis',
2854
+ 'white-space:nowrap',
2855
+ ].join(';');
2856
+ const value = doc.createElement('div');
2857
+ value.textContent = detail.value;
2858
+ value.style.cssText = [
2859
+ `color:${detail.tone === 'warning' ? 'var(--fps-editor-warn)' : detail.tone === 'error' ? 'var(--fps-editor-danger-strong)' : detail.tone === 'success' ? 'var(--fps-editor-success)' : 'var(--fps-editor-text-strong)'}`,
2860
+ 'font-size:12px',
2861
+ 'font-weight:900',
2862
+ 'line-height:1.35',
2863
+ 'overflow:hidden',
2864
+ 'text-overflow:ellipsis',
2865
+ 'white-space:nowrap',
2866
+ ].join(';');
2867
+ item.appendChild(label);
2868
+ item.appendChild(value);
2869
+ staticShadowBakeDetails.appendChild(item);
2870
+ }
2871
+ }
2359
2872
  function openToolbarOverflowMenu() {
2360
2873
  if (toolbarOverflowMenu.childElementCount === 0)
2361
2874
  return;
@@ -2450,6 +2963,8 @@ export function createLocalEditorBrowserUi(options = {}) {
2450
2963
  return;
2451
2964
  closeLocalTestMenu();
2452
2965
  closeToolbarOverflowMenu();
2966
+ if (!target.closest('[data-editor-toolbar-static-shadow-bake-popover]'))
2967
+ closeStaticShadowBakePopover();
2453
2968
  closeSnapSettingsPopover();
2454
2969
  closePlacementSettingsPopover();
2455
2970
  closeTransformActionPopover();
@@ -2484,6 +2999,9 @@ export function createLocalEditorBrowserUi(options = {}) {
2484
2999
  });
2485
3000
  undoButton.addEventListener('click', () => callbacks.onUndo?.());
2486
3001
  redoButton.addEventListener('click', () => callbacks.onRedo?.());
3002
+ performanceMonitorButton.addEventListener('click', () => {
3003
+ setPerformanceMonitorOpen(!performanceMonitorOpen);
3004
+ });
2487
3005
  gridToggleButton.addEventListener('click', () => {
2488
3006
  const visible = currentState?.grid?.visible ?? true;
2489
3007
  callbacks.onGridVisibleChange?.(!visible);
@@ -2492,6 +3010,16 @@ export function createLocalEditorBrowserUi(options = {}) {
2492
3010
  const enabled = currentState?.sceneCameraPreview?.enabled ?? false;
2493
3011
  callbacks.onSceneCameraPreviewToggle?.(!enabled);
2494
3012
  });
3013
+ staticShadowBakeButton.addEventListener('click', () => {
3014
+ if (staticShadowBakeButton.disabled)
3015
+ return;
3016
+ const action = findLocalEditorRenderingAction(currentState?.renderingPanel, STATIC_SHADOW_BAKE_ACTION_ID);
3017
+ if (!action || action.action.disabled)
3018
+ return;
3019
+ openStaticShadowBakePopover();
3020
+ callbacks.onRenderingAction?.({ actionId: STATIC_SHADOW_BAKE_ACTION_ID });
3021
+ });
3022
+ staticShadowBakePopoverClose.addEventListener('click', () => closeStaticShadowBakePopover());
2495
3023
  const toggleCoordinateAxesProjection = (event) => {
2496
3024
  event.preventDefault();
2497
3025
  event.stopPropagation();
@@ -2553,6 +3081,17 @@ export function createLocalEditorBrowserUi(options = {}) {
2553
3081
  shortcutHelpPanel.style.display = helpOpen ? 'flex' : 'none';
2554
3082
  LocalEditorShared.applyButtonActiveState(sceneHelpButton, helpOpen);
2555
3083
  };
3084
+ const setPerformanceMonitorOpen = (open, notify = true) => {
3085
+ if (performanceMonitorOpen === open)
3086
+ return;
3087
+ if (open)
3088
+ contextMenu.close();
3089
+ performanceMonitorOpen = open;
3090
+ LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
3091
+ renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' ? currentState.performanceStats ?? null : null, currentState?.mode === 'editor' && performanceMonitorOpen);
3092
+ if (notify)
3093
+ callbacks.onPerformanceMonitorOpenChange?.(performanceMonitorOpen);
3094
+ };
2556
3095
  const openAssetPreviewModal = (asset) => {
2557
3096
  if (!asset.preview)
2558
3097
  return;
@@ -3326,6 +3865,23 @@ export function createLocalEditorBrowserUi(options = {}) {
3326
3865
  });
3327
3866
  inspectorPanel.addEventListener('click', (event) => {
3328
3867
  const target = event.target instanceof HTMLElement ? event.target : null;
3868
+ const renderingActionButton = target?.closest('[data-editor-rendering-action]');
3869
+ if (renderingActionButton) {
3870
+ if (renderingActionButton.disabled)
3871
+ return;
3872
+ const actionInput = createRenderingActionInput(renderingActionButton);
3873
+ if (!actionInput)
3874
+ return;
3875
+ const action = findLocalEditorRenderingAction(currentState?.renderingPanel, actionInput.actionId);
3876
+ if (!action || action.action.disabled)
3877
+ return;
3878
+ event.preventDefault();
3879
+ event.stopPropagation();
3880
+ if (actionInput.actionId === STATIC_SHADOW_BAKE_ACTION_ID)
3881
+ openStaticShadowBakePopover();
3882
+ callbacks.onRenderingAction?.(actionInput);
3883
+ return;
3884
+ }
3329
3885
  const vectorLockButton = target?.closest('[data-editor-inspector-vector-lock]');
3330
3886
  if (vectorLockButton) {
3331
3887
  const groupPath = vectorLockButton.dataset.editorInspectorVectorLock;
@@ -3520,11 +4076,13 @@ export function createLocalEditorBrowserUi(options = {}) {
3520
4076
  return;
3521
4077
  if (actionButton.disabled)
3522
4078
  return;
3523
- const actionId = actionButton.dataset.editorRenderingAction;
3524
- if (!actionId)
4079
+ const actionInput = createRenderingActionInput(actionButton);
4080
+ if (!actionInput)
3525
4081
  return;
3526
4082
  event.preventDefault();
3527
- callbacks.onRenderingAction?.({ actionId });
4083
+ if (actionInput.actionId === STATIC_SHADOW_BAKE_ACTION_ID)
4084
+ openStaticShadowBakePopover();
4085
+ callbacks.onRenderingAction?.(actionInput);
3528
4086
  });
3529
4087
  const onKeyDown = (event) => {
3530
4088
  if (event.defaultPrevented)
@@ -3562,6 +4120,11 @@ export function createLocalEditorBrowserUi(options = {}) {
3562
4120
  closeOverlaySettingsPopover();
3563
4121
  return;
3564
4122
  }
4123
+ if (key === 'escape' && staticShadowBakePopoverOpen) {
4124
+ event.preventDefault();
4125
+ closeStaticShadowBakePopover();
4126
+ return;
4127
+ }
3565
4128
  const primaryModifier = event.metaKey || event.ctrlKey;
3566
4129
  const handleDocumentShortcut = inputRouter.shouldHandleDocumentShortcut(event);
3567
4130
  const handleGlobalShortcut = inputRouter.shouldHandleGlobalShortcut(event);
@@ -3673,6 +4236,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3673
4236
  : statusToneColor;
3674
4237
  renderCoordinateAxesOverlay(coordinateAxesOverlay, inEditor ? state.coordinateAxes ?? null : null);
3675
4238
  renderSceneFrameRateOverlay(sceneFrameRateOverlay, inEditor ? state.sceneFrameStats ?? null : null);
4239
+ renderPerformanceMonitorOverlay(performanceMonitorOverlay, inEditor ? state.performanceStats ?? null : null, inEditor && performanceMonitorOpen);
3676
4240
  renderSpatialOverlay(spatialOverlay, inEditor ? state.viewportSpatialOverlay ?? null : null);
3677
4241
  renderMeasurementOverlay(measurementOverlay, inEditor ? state.viewportMeasurement ?? null : null);
3678
4242
  const boxSelection = state.boxSelection;
@@ -3719,7 +4283,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3719
4283
  contextMenu.close();
3720
4284
  hostChrome.style.display = !inEditor && localTestActionsEnabled ? 'flex' : 'none';
3721
4285
  enterEditorButton.disabled = disabled;
3722
- for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, gridToggleButton]) {
4286
+ for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, performanceMonitorButton, gridToggleButton]) {
3723
4287
  button.style.display = 'inline-flex';
3724
4288
  button.disabled = disabled;
3725
4289
  }
@@ -3729,6 +4293,8 @@ export function createLocalEditorBrowserUi(options = {}) {
3729
4293
  closeLocalTestMenu();
3730
4294
  if (!inEditor)
3731
4295
  helpOpen = false;
4296
+ if (!inEditor && performanceMonitorOpen)
4297
+ setPerformanceMonitorOpen(false);
3732
4298
  if (!inEditor || disabled) {
3733
4299
  assetPreviewOpen = false;
3734
4300
  previewedAsset = null;
@@ -3749,6 +4315,20 @@ export function createLocalEditorBrowserUi(options = {}) {
3749
4315
  closeTransformActionPopover();
3750
4316
  if (!inEditor)
3751
4317
  closeOverlaySettingsPopover();
4318
+ if (!inEditor)
4319
+ closeStaticShadowBakePopover();
4320
+ const staticShadowBakeAction = findLocalEditorRenderingAction(state.renderingPanel, STATIC_SHADOW_BAKE_ACTION_ID);
4321
+ const staticShadowBakeVisible = inEditor && !!staticShadowBakeAction;
4322
+ staticShadowBakeGroup.style.display = staticShadowBakeVisible ? 'flex' : 'none';
4323
+ const staticShadowBakeDisabled = disabled || !staticShadowBakeAction || staticShadowBakeAction.action.disabled === true;
4324
+ staticShadowBakeButton.disabled = staticShadowBakeDisabled;
4325
+ staticShadowBakeButton.style.opacity = staticShadowBakeDisabled ? '0.62' : '1';
4326
+ staticShadowBakeButton.style.cursor = staticShadowBakeDisabled ? 'not-allowed' : 'pointer';
4327
+ const staticShadowBakeIcon = staticShadowBakeAction?.action.icon;
4328
+ setToolbarButtonIcon(doc, staticShadowBakeButton, isLocalEditorIconName(staticShadowBakeIcon) ? staticShadowBakeIcon : 'save');
4329
+ setToolbarButtonTooltip(staticShadowBakeButton, staticShadowBakeAction?.action.tooltip ?? staticShadowBakeAction?.action.label ?? '烘焙静态阴影');
4330
+ LocalEditorShared.applyButtonActiveState(staticShadowBakeButton, !!staticShadowBakeAction?.system?.progress);
4331
+ renderStaticShadowBakePopover(state);
3752
4332
  const sceneCameraPreview = state.sceneCameraPreview ?? { enabled: false, available: false };
3753
4333
  cameraPreviewGroup.style.display = inEditor ? 'flex' : 'none';
3754
4334
  sceneCameraButton.disabled = disabled || !sceneCameraPreview.available;
@@ -3798,6 +4378,9 @@ export function createLocalEditorBrowserUi(options = {}) {
3798
4378
  if (!inEditor || disabled || viewportToolsGroup.style.display === 'none')
3799
4379
  closeOverlaySettingsPopover();
3800
4380
  const gridState = state.grid ?? { visible: false, available: false };
4381
+ performanceMonitorButton.disabled = disabled;
4382
+ setToolbarButtonTooltip(performanceMonitorButton, performanceMonitorOpen ? '隐藏性能监控' : '显示性能监控');
4383
+ LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
3801
4384
  gridToggleButton.disabled = disabled || !gridState.available;
3802
4385
  setToolbarButtonTooltip(gridToggleButton, gridState.visible ? '隐藏 Scene View 网格' : '显示 Scene View 网格');
3803
4386
  LocalEditorShared.applyButtonActiveState(gridToggleButton, gridState.visible);
@@ -3915,8 +4498,15 @@ export function createLocalEditorBrowserUi(options = {}) {
3915
4498
  },
3916
4499
  updatePreview,
3917
4500
  updateSceneFrameStats(stats) {
4501
+ if (currentState)
4502
+ currentState = { ...currentState, sceneFrameStats: stats };
3918
4503
  renderSceneFrameRateOverlay(sceneFrameRateOverlay, currentState?.mode === 'editor' ? stats : null);
3919
4504
  },
4505
+ updatePerformanceStats(stats) {
4506
+ if (currentState)
4507
+ currentState = { ...currentState, performanceStats: stats };
4508
+ renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' ? stats : null, currentState?.mode === 'editor' && performanceMonitorOpen);
4509
+ },
3920
4510
  setTheme(theme) {
3921
4511
  setActiveTheme(theme);
3922
4512
  },
@@ -3944,6 +4534,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3944
4534
  spatialOverlay.root.remove();
3945
4535
  measurementOverlay.root.remove();
3946
4536
  sceneFrameRateOverlay.root.remove();
4537
+ performanceMonitorOverlay.root.remove();
3947
4538
  boxSelectionOverlay.remove();
3948
4539
  shortcutHelpPanel.remove();
3949
4540
  assetPreviewModal.remove();