@fps-games/editor 0.1.4-beta.4 → 0.1.5-beta.1

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