@fps-games/editor 0.1.5-beta.4 → 0.1.6-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.
- package/dist/build-info.json +16 -16
- package/dist/local-editor-agent-actions.d.ts +8 -1
- package/dist/local-editor-agent-actions.d.ts.map +1 -1
- package/dist/local-editor-agent-actions.js +171 -12
- package/dist/local-editor-agent-actions.js.map +1 -1
- package/dist/local-editor-agent-context.d.ts +29 -1
- package/dist/local-editor-agent-context.d.ts.map +1 -1
- package/dist/local-editor-agent-context.js +403 -0
- package/dist/local-editor-agent-context.js.map +1 -1
- package/dist/local-editor-harness.d.ts +103 -5
- package/dist/local-editor-harness.d.ts.map +1 -1
- package/dist/local-editor-harness.js +1982 -101
- package/dist/local-editor-harness.js.map +1 -1
- package/dist/local-editor-marker-graph.d.ts +92 -0
- package/dist/local-editor-marker-graph.d.ts.map +1 -0
- package/dist/local-editor-marker-graph.js +1432 -0
- package/dist/local-editor-marker-graph.js.map +1 -0
- package/dist/local-editor-performance-stats.js +1 -1
- package/dist/local-editor-performance-stats.js.map +1 -1
- package/dist/playable-babylon-facade.d.ts +2 -2
- package/dist/playable-babylon-facade.d.ts.map +1 -1
- package/dist/playable-babylon-facade.js +1 -1
- package/dist/playable-babylon-facade.js.map +1 -1
- package/dist/playable-local-editor-host.d.ts +52 -7
- package/dist/playable-local-editor-host.d.ts.map +1 -1
- package/dist/playable-local-editor-host.js +23 -1
- package/dist/playable-local-editor-host.js.map +1 -1
- package/dist/playable-sdk.d.ts +4 -2
- package/dist/playable-sdk.d.ts.map +1 -1
- package/dist/playable-sdk.js +2 -1
- package/dist/playable-sdk.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +11 -0
- package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts +3 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js +114 -18
- package/node_modules/@fps-games/editor-babylon/dist/editor-sky.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.js +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/editor-world.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/index.js +3 -0
- package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts +52 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +1395 -0
- package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js +4 -65
- package/node_modules/@fps-games/editor-babylon/dist/material-property-adapter.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts +28 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js +235 -0
- package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts +37 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js +451 -0
- package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js +24 -10
- package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js +20 -4
- package/node_modules/@fps-games/editor-babylon/dist/projection-pick-resolver.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts +9 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js +64 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection-source-owner-path.js.map +1 -0
- package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +44 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-babylon/dist/projection.js +311 -70
- package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
- package/node_modules/@fps-games/editor-babylon/package.json +5 -5
- package/node_modules/@fps-games/editor-browser/dist/index.d.ts +5 -2
- package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/index.js +2 -0
- package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts +5 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +23 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +69 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +2 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +38 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +8 -2
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +7 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panel-registry.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +4 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +1471 -29
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +52 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +131 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -0
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +9 -2
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +234 -3
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +10 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +3 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +4 -3
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +1274 -55
- package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
- package/node_modules/@fps-games/editor-browser/package.json +3 -3
- package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +1 -1
- package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +2 -0
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +1 -0
- package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
- package/node_modules/@fps-games/editor-core/package.json +2 -2
- package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +17 -3
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts +3 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js +68 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/document.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-placement/index.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +56 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +531 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +103 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/index.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js +9 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/schema.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js +3 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/field-schema/validators.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js +3 -7
- package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js +6 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/binding.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts +2 -10
- package/node_modules/@fps-games/editor-playable-sdk/dist/material-binding/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +8 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +66 -31
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +40 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts +1 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js +20 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/descriptors.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +68 -27
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js +7 -4
- package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/object.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
- package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +57 -3
- package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +19 -0
- package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/index.js +1 -0
- package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts +128 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.d.ts.map +1 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js +2 -0
- package/node_modules/@fps-games/editor-protocol/dist/marker-graph.js.map +1 -0
- package/node_modules/@fps-games/editor-protocol/package.json +1 -1
- package/package.json +8 -8
|
@@ -8,7 +8,7 @@ import { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, resolveLocalEditorBrowserInsp
|
|
|
8
8
|
import { DEFAULT_EDITOR_TRANSFORM_OPERATION_SETTINGS, DEFAULT_EDITOR_TRANSFORM_TOOL_DESCRIPTORS, } from '@fps-games/editor-core';
|
|
9
9
|
export { createLocalEditorViewportRevealController, isLocalEditorElementVisibleInViewport, resolveLocalEditorViewportRevealScrollTop, revealLocalEditorElementInViewport, } from './local-editor-ui-dock-panel.js';
|
|
10
10
|
export { createLocalEditorHierarchyBlankMenu, createLocalEditorHierarchyCopyShortcutAction, createLocalEditorHierarchyDeleteShortcutAction, createLocalEditorHierarchyDuplicateShortcutAction, createLocalEditorHierarchyNodeMenu, createLocalEditorHierarchyPasteShortcutAction, createLocalEditorHierarchySelectAllShortcutAction, } from './local-editor-ui-hierarchy-actions.js';
|
|
11
|
-
export { createLocalEditorHierarchyController, } from './local-editor-ui-hierarchy-controller.js';
|
|
11
|
+
export { createLocalEditorHierarchyController, resolveLocalEditorHierarchyCreateMarkerParentId, } from './local-editor-ui-hierarchy-controller.js';
|
|
12
12
|
export { resolveLocalEditorHierarchySearchRows, } from './local-editor-ui-hierarchy-view.js';
|
|
13
13
|
export { createLocalEditorHierarchyAttachDialog, resolveLocalEditorHierarchyAttachTargets, } from './local-editor-ui-hierarchy-attach-dialog.js';
|
|
14
14
|
export { canLocalEditorHierarchyNodeHaveChildren, createLocalEditorHierarchyTreeModel, isLocalEditorHierarchyNodeSelectable, isLocalEditorHierarchyNodeMovable, } from './local-editor-ui-hierarchy-tree.js';
|
|
@@ -22,6 +22,8 @@ import { createShortcutHelpPanel as createLocalEditorShortcutHelpPanel } from '.
|
|
|
22
22
|
import { applyLocalEditorTheme, ensureLocalEditorTheme, LOCAL_EDITOR_THEME_CLASS, normalizeLocalEditorThemeName, } from './local-editor-ui-theme.js';
|
|
23
23
|
import { createDefaultLocalEditorWorkbenchLayout, createLocalEditorWorkbenchLayoutController, createLocalEditorWorkbench, createSceneHeaderToolbar, createWorkbenchPanelContent, } from './local-editor-ui-workbench.js';
|
|
24
24
|
import { createLocalEditorIcon, isLocalEditorIconName } from './local-editor-ui-icons.js';
|
|
25
|
+
import { resolveLocalEditorBrowserAssetKind, } from './local-editor-ui-asset-kind.js';
|
|
26
|
+
import { createLocalEditorPrefabStageTitle, filterLocalEditorPrefabStageStructureItems, findLocalEditorPrefabStageStructureItem, formatLocalEditorPrefabStageComparisonPreviewStatus, LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX, resolveLocalEditorRightDockVisibility, resolveLocalEditorPrefabStageComparisonPreviewTone, shouldLocalEditorClosePerformanceMonitor, shouldLocalEditorPrefabStageBlockHierarchyShortcut, shouldShowLocalEditorPrefabComparisonColumn, shouldToggleLocalEditorPrefabComparisonShortcut, } from './local-editor-ui-prefab-stage.js';
|
|
25
27
|
export { applyLocalEditorBrowserInspectorControlBinding, createLocalEditorBrowserInspectorControlRegistry, formatLocalEditorBrowserInspectorNumberValue, formatLocalEditorBrowserInspectorValue, parseLocalEditorBrowserInspectorNumberValue, resolveLocalEditorBrowserInspectorSectionStatus, resolveLocalEditorBrowserInspectorControlRegistration, } from './local-editor-ui-panels.js';
|
|
26
28
|
export { createLocalEditorBrowserInspectorGroupValueClipboardPayload, createLocalEditorBrowserInspectorVectorCopyPayload, parseLocalEditorBrowserInspectorGroupValueClipboardPayload, } from './local-editor-inspector-clipboard.js';
|
|
27
29
|
export { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, isLocalEditorBrowserInspectorTransformVectorGroupPath, resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromProperties, } from './local-editor-inspector-groups.js';
|
|
@@ -66,8 +68,24 @@ function readInspectorInputValue(input, source) {
|
|
|
66
68
|
b: (numeric & 255) / 255,
|
|
67
69
|
};
|
|
68
70
|
}
|
|
71
|
+
if (input.dataset.serializedJsonValue === 'true') {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = JSON.parse(input.value);
|
|
74
|
+
return isInspectorSerializedInputValue(parsed) ? parsed : null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
69
80
|
return input.value;
|
|
70
81
|
}
|
|
82
|
+
function isInspectorSerializedInputValue(value) {
|
|
83
|
+
return value == null
|
|
84
|
+
|| typeof value === 'number'
|
|
85
|
+
|| typeof value === 'string'
|
|
86
|
+
|| typeof value === 'boolean'
|
|
87
|
+
|| (!!value && typeof value === 'object' && !Array.isArray(value));
|
|
88
|
+
}
|
|
71
89
|
const TRANSFORM_TOOL_ICONS = {
|
|
72
90
|
select: 'select',
|
|
73
91
|
move: 'move',
|
|
@@ -206,7 +224,8 @@ function createInspectorPropertyInputs(input, source, lockedVectorGroups) {
|
|
|
206
224
|
if (!propertyInput)
|
|
207
225
|
return null;
|
|
208
226
|
const groupPath = resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath(propertyInput.path);
|
|
209
|
-
|
|
227
|
+
const forceVectorLock = input.dataset.serializedForceVectorLock === 'true';
|
|
228
|
+
if (!groupPath || (!forceVectorLock && !lockedVectorGroups.has(groupPath)))
|
|
210
229
|
return [propertyInput];
|
|
211
230
|
if (propertyInput.control !== 'number' || propertyInput.valueType !== 'number')
|
|
212
231
|
return [propertyInput];
|
|
@@ -352,6 +371,33 @@ function createRenderingActionInput(button) {
|
|
|
352
371
|
...(params ? { params } : {}),
|
|
353
372
|
};
|
|
354
373
|
}
|
|
374
|
+
function createInspectorActionInput(button) {
|
|
375
|
+
const actionId = button.dataset.editorInspectorAction;
|
|
376
|
+
if (!actionId)
|
|
377
|
+
return null;
|
|
378
|
+
const params = parseRenderingActionParams(button.dataset.editorInspectorActionParams);
|
|
379
|
+
const targetIds = parseInspectorActionTargetIds(button.dataset.editorInspectorActionTargetIds);
|
|
380
|
+
return {
|
|
381
|
+
actionId,
|
|
382
|
+
targetId: button.dataset.editorInspectorActionTargetId || null,
|
|
383
|
+
targetIds,
|
|
384
|
+
path: button.dataset.editorInspectorActionPath,
|
|
385
|
+
...(params ? { params } : {}),
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function parseInspectorActionTargetIds(value) {
|
|
389
|
+
if (!value)
|
|
390
|
+
return undefined;
|
|
391
|
+
try {
|
|
392
|
+
const parsed = JSON.parse(value);
|
|
393
|
+
return Array.isArray(parsed) && parsed.every(item => typeof item === 'string')
|
|
394
|
+
? parsed
|
|
395
|
+
: undefined;
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
355
401
|
function parseRenderingActionParams(value) {
|
|
356
402
|
if (!value)
|
|
357
403
|
return null;
|
|
@@ -371,7 +417,40 @@ function readInspectorCommitMode(input) {
|
|
|
371
417
|
function readRenderingCommitMode(input) {
|
|
372
418
|
return input.dataset.renderingCommitMode ?? 'live';
|
|
373
419
|
}
|
|
420
|
+
function isLocalEditorRightDockTab(value) {
|
|
421
|
+
return value === 'inspector' || value === 'rendering' || value === 'markers';
|
|
422
|
+
}
|
|
374
423
|
function resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter) {
|
|
424
|
+
if (tab === 'markers') {
|
|
425
|
+
const markerPanel = state.markerPanel;
|
|
426
|
+
if (!markerPanel)
|
|
427
|
+
return 'markers:none';
|
|
428
|
+
return [
|
|
429
|
+
'markers',
|
|
430
|
+
markerPanel.activeMarkerId ?? '',
|
|
431
|
+
markerPanel.markersVisible === false ? 'markers-hidden' : 'markers-visible',
|
|
432
|
+
markerPanel.status ?? '',
|
|
433
|
+
markerPanel.markerTypes.map(markerType => [
|
|
434
|
+
markerType.type,
|
|
435
|
+
markerType.label,
|
|
436
|
+
markerType.kind ?? '',
|
|
437
|
+
markerType.description ?? '',
|
|
438
|
+
markerType.usedByCount ?? 0,
|
|
439
|
+
].join('=')).join(';'),
|
|
440
|
+
(markerPanel.relations ?? []).map(relation => [
|
|
441
|
+
relation.id,
|
|
442
|
+
relation.type,
|
|
443
|
+
relation.from.kind,
|
|
444
|
+
relation.from.id,
|
|
445
|
+
relation.from.visibility ?? '',
|
|
446
|
+
relation.to.kind,
|
|
447
|
+
relation.to.id,
|
|
448
|
+
relation.to.visibility ?? '',
|
|
449
|
+
relation.selected ? 'selected' : '',
|
|
450
|
+
relation.status ?? '',
|
|
451
|
+
].join('=')).join(';'),
|
|
452
|
+
].join(':');
|
|
453
|
+
}
|
|
375
454
|
if (tab === 'rendering') {
|
|
376
455
|
const rendering = state.renderingPanel;
|
|
377
456
|
if (!rendering)
|
|
@@ -396,20 +475,22 @@ function resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter) {
|
|
|
396
475
|
inspectorFilter,
|
|
397
476
|
].join(':');
|
|
398
477
|
}
|
|
399
|
-
function findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel) {
|
|
400
|
-
const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
|
|
478
|
+
function findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel, markersPanel) {
|
|
479
|
+
const panel = tab === 'inspector' ? inspectorPanel : tab === 'rendering' ? renderingPanel : markersPanel;
|
|
401
480
|
const selector = tab === 'inspector'
|
|
402
481
|
? '[data-editor-inspector-scroll-viewport]'
|
|
403
|
-
: '
|
|
482
|
+
: tab === 'rendering'
|
|
483
|
+
? '[data-editor-rendering-scroll-viewport]'
|
|
484
|
+
: '[data-editor-markers-scroll-viewport]';
|
|
404
485
|
return panel.querySelector(selector) ?? panel;
|
|
405
486
|
}
|
|
406
|
-
function captureLocalEditorRightDockScrollSnapshot(state, tab, inspectorFilter, inspectorPanel, renderingPanel) {
|
|
487
|
+
function captureLocalEditorRightDockScrollSnapshot(state, tab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel) {
|
|
407
488
|
if (!state || state.mode !== 'editor')
|
|
408
489
|
return null;
|
|
409
|
-
const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel);
|
|
490
|
+
const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel, markersPanel);
|
|
410
491
|
if (!viewport)
|
|
411
492
|
return null;
|
|
412
|
-
const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
|
|
493
|
+
const panel = tab === 'inspector' ? inspectorPanel : tab === 'rendering' ? renderingPanel : markersPanel;
|
|
413
494
|
return {
|
|
414
495
|
tab,
|
|
415
496
|
contentKey: resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter),
|
|
@@ -418,15 +499,15 @@ function captureLocalEditorRightDockScrollSnapshot(state, tab, inspectorFilter,
|
|
|
418
499
|
scrollTop: viewport.scrollTop,
|
|
419
500
|
};
|
|
420
501
|
}
|
|
421
|
-
function restoreLocalEditorRightDockScrollSnapshot(snapshot, state, tab, inspectorFilter, inspectorPanel, renderingPanel) {
|
|
502
|
+
function restoreLocalEditorRightDockScrollSnapshot(snapshot, state, tab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel) {
|
|
422
503
|
if (!snapshot || snapshot.tab !== tab || state.mode !== 'editor')
|
|
423
504
|
return;
|
|
424
|
-
const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
|
|
505
|
+
const panel = tab === 'inspector' ? inspectorPanel : tab === 'rendering' ? renderingPanel : markersPanel;
|
|
425
506
|
if ((panel.dataset.editorPanelId ?? tab) !== snapshot.panelId)
|
|
426
507
|
return;
|
|
427
508
|
if (resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter) !== snapshot.contentKey)
|
|
428
509
|
return;
|
|
429
|
-
const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel);
|
|
510
|
+
const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel, markersPanel);
|
|
430
511
|
if (!viewport)
|
|
431
512
|
return;
|
|
432
513
|
viewport.scrollLeft = snapshot.scrollLeft;
|
|
@@ -455,6 +536,132 @@ function readRenderingImmediateSource(input) {
|
|
|
455
536
|
return 'list';
|
|
456
537
|
return 'input';
|
|
457
538
|
}
|
|
539
|
+
function createMarkerTypeActionInput(button) {
|
|
540
|
+
const action = button.dataset.editorMarkerTypeAction;
|
|
541
|
+
if (action === 'create') {
|
|
542
|
+
const block = button.closest('[data-editor-marker-type-create]');
|
|
543
|
+
if (!block)
|
|
544
|
+
return null;
|
|
545
|
+
const type = readMarkerTypeFieldValue(block, 'type');
|
|
546
|
+
if (!type)
|
|
547
|
+
return null;
|
|
548
|
+
const label = readMarkerTypeFieldValue(block, 'label') || type;
|
|
549
|
+
return {
|
|
550
|
+
action: 'create',
|
|
551
|
+
type,
|
|
552
|
+
label,
|
|
553
|
+
kind: readMarkerTypeFieldValue(block, 'kind') || undefined,
|
|
554
|
+
description: readMarkerTypeFieldValue(block, 'description') || undefined,
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
const row = button.closest('[data-editor-marker-type-row]');
|
|
558
|
+
const type = row?.dataset.editorMarkerTypeRow?.trim() ?? '';
|
|
559
|
+
if (!row || !type)
|
|
560
|
+
return null;
|
|
561
|
+
if (action === 'delete')
|
|
562
|
+
return { action: 'delete', type };
|
|
563
|
+
if (action !== 'update')
|
|
564
|
+
return null;
|
|
565
|
+
return {
|
|
566
|
+
action: 'update',
|
|
567
|
+
type,
|
|
568
|
+
label: readMarkerTypeFieldValue(row, 'label') || type,
|
|
569
|
+
kind: readMarkerTypeFieldValue(row, 'kind') || undefined,
|
|
570
|
+
description: readMarkerTypeFieldValue(row, 'description'),
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function createMarkerRelationActionInput(target) {
|
|
574
|
+
const action = target.dataset.editorMarkerRelationAction;
|
|
575
|
+
if (action === 'delete') {
|
|
576
|
+
const row = target.closest('[data-editor-marker-relation-row]');
|
|
577
|
+
const relationId = row?.dataset.editorMarkerRelationRow?.trim() ?? '';
|
|
578
|
+
return relationId ? { action: 'delete', relationId } : null;
|
|
579
|
+
}
|
|
580
|
+
if (action === 'reverse') {
|
|
581
|
+
const row = target.closest('[data-editor-marker-relation-row]');
|
|
582
|
+
const relationId = row?.dataset.editorMarkerRelationRow?.trim() ?? '';
|
|
583
|
+
return relationId ? { action: 'reverse', relationId } : null;
|
|
584
|
+
}
|
|
585
|
+
if (action === 'delete-connected') {
|
|
586
|
+
const markerId = target.dataset.editorMarkerRelationMarkerId?.trim() ?? '';
|
|
587
|
+
return { action: 'delete-connected', ...(markerId ? { markerId } : {}) };
|
|
588
|
+
}
|
|
589
|
+
if (action === 'select') {
|
|
590
|
+
const row = target.closest('[data-editor-marker-relation-row]');
|
|
591
|
+
const relationId = row?.dataset.editorMarkerRelationRow?.trim() ?? '';
|
|
592
|
+
return relationId ? { action: 'select', relationId } : null;
|
|
593
|
+
}
|
|
594
|
+
if (action === 'pick-cancel')
|
|
595
|
+
return { action: 'pick-cancel' };
|
|
596
|
+
if (action !== 'create' && action !== 'pick-start')
|
|
597
|
+
return null;
|
|
598
|
+
const block = target.closest('[data-editor-marker-relation-create]');
|
|
599
|
+
if (!block)
|
|
600
|
+
return null;
|
|
601
|
+
const type = readMarkerRelationTypeFieldValue(block);
|
|
602
|
+
const from = readMarkerRelationEndpointFieldValue(block, 'from');
|
|
603
|
+
const to = readMarkerRelationEndpointFieldValue(block, 'to');
|
|
604
|
+
if (!type || !from || (action === 'create' && !to))
|
|
605
|
+
return null;
|
|
606
|
+
const directed = readMarkerRelationDirectionFieldValue(block);
|
|
607
|
+
if (action === 'pick-start') {
|
|
608
|
+
return {
|
|
609
|
+
action: 'pick-start',
|
|
610
|
+
type,
|
|
611
|
+
fromKind: from.kind,
|
|
612
|
+
fromId: from.id,
|
|
613
|
+
...(directed === null ? {} : { directed }),
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
return {
|
|
617
|
+
action: 'create',
|
|
618
|
+
type,
|
|
619
|
+
fromKind: from.kind,
|
|
620
|
+
fromId: from.id,
|
|
621
|
+
toKind: to.kind,
|
|
622
|
+
toId: to.id,
|
|
623
|
+
...(directed === null ? {} : { directed }),
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
function readMarkerTypeFieldValue(parent, field) {
|
|
627
|
+
const input = parent.querySelector(`[data-editor-marker-type-field="${field}"]`);
|
|
628
|
+
return input?.value.trim() ?? '';
|
|
629
|
+
}
|
|
630
|
+
function readMarkerRelationTypeFieldValue(parent) {
|
|
631
|
+
const select = parent.querySelector('[data-editor-marker-relation-field="type"]');
|
|
632
|
+
return select?.value.trim() ?? '';
|
|
633
|
+
}
|
|
634
|
+
function readMarkerRelationDirectionFieldValue(parent) {
|
|
635
|
+
const select = parent.querySelector('[data-editor-marker-relation-field="directed"]');
|
|
636
|
+
if (!select || select.value === 'default')
|
|
637
|
+
return null;
|
|
638
|
+
return select.value === 'true';
|
|
639
|
+
}
|
|
640
|
+
function readMarkerRelationEndpointFieldValue(parent, field) {
|
|
641
|
+
const select = parent.querySelector(`[data-editor-marker-relation-field="${field}"]`);
|
|
642
|
+
const option = select?.selectedOptions.item(0) ?? null;
|
|
643
|
+
const kind = option?.dataset.editorMarkerRelationEndpointKind?.trim();
|
|
644
|
+
const id = option?.dataset.editorMarkerRelationEndpointId?.trim();
|
|
645
|
+
if (kind && id)
|
|
646
|
+
return { kind, id };
|
|
647
|
+
return decodeMarkerRelationEndpointValue(select?.value);
|
|
648
|
+
}
|
|
649
|
+
function decodeMarkerRelationEndpointValue(value) {
|
|
650
|
+
const raw = value?.trim();
|
|
651
|
+
if (!raw)
|
|
652
|
+
return null;
|
|
653
|
+
const separator = raw.indexOf(':');
|
|
654
|
+
if (separator <= 0)
|
|
655
|
+
return null;
|
|
656
|
+
const kind = raw.slice(0, separator);
|
|
657
|
+
const encodedId = raw.slice(separator + 1);
|
|
658
|
+
try {
|
|
659
|
+
return { kind, id: decodeURIComponent(encodedId) };
|
|
660
|
+
}
|
|
661
|
+
catch {
|
|
662
|
+
return { kind, id: encodedId };
|
|
663
|
+
}
|
|
664
|
+
}
|
|
458
665
|
function markLocalEditorKeyboardCommittedValue(input) {
|
|
459
666
|
input.dataset.editorKeyboardCommittedValue = input.value;
|
|
460
667
|
}
|
|
@@ -764,6 +971,50 @@ const PERFORMANCE_MONITOR_METRIC_GROUPS = [
|
|
|
764
971
|
],
|
|
765
972
|
},
|
|
766
973
|
];
|
|
974
|
+
const PREFAB_IMPORT_STATS_METRICS = [
|
|
975
|
+
{
|
|
976
|
+
key: 'source',
|
|
977
|
+
label: 'Source',
|
|
978
|
+
description: '当前 prefab preview 使用的 source model 或 source url。',
|
|
979
|
+
format: stats => stats?.sourceId ?? stats?.assetId ?? '--',
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
key: 'nodes',
|
|
983
|
+
label: 'Nodes',
|
|
984
|
+
description: 'Babylon 导入后 runtime snapshot 中的节点总数,包含虚拟 root。',
|
|
985
|
+
format: stats => formatPerformanceInteger(stats?.nodeCount ?? null),
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
key: 'transforms',
|
|
989
|
+
label: 'Transforms',
|
|
990
|
+
description: 'runtime snapshot 中 root/transform 节点数量。',
|
|
991
|
+
format: stats => formatPerformanceInteger(stats?.transformCount ?? null),
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
key: 'meshes',
|
|
995
|
+
label: 'Meshes',
|
|
996
|
+
description: 'runtime snapshot 中可渲染 mesh 节点数量。',
|
|
997
|
+
format: stats => formatPerformanceInteger(stats?.meshCount ?? null),
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
key: 'materials',
|
|
1001
|
+
label: 'Materials',
|
|
1002
|
+
description: 'runtime snapshot 关联到的材质数量。',
|
|
1003
|
+
format: stats => formatPerformanceInteger(stats?.materialCount ?? null),
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
key: 'textures',
|
|
1007
|
+
label: 'Textures',
|
|
1008
|
+
description: 'runtime snapshot 关联到的贴图数量。',
|
|
1009
|
+
format: stats => formatPerformanceInteger(stats?.textureCount ?? null),
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
key: 'animations',
|
|
1013
|
+
label: 'Animations',
|
|
1014
|
+
description: 'runtime snapshot 关联到的 animation group 数量。',
|
|
1015
|
+
format: stats => formatPerformanceInteger(stats?.animationCount ?? null),
|
|
1016
|
+
},
|
|
1017
|
+
];
|
|
767
1018
|
function createSceneFrameRateOverlay(doc) {
|
|
768
1019
|
const root = doc.createElement('div');
|
|
769
1020
|
root.classList.add(LOCAL_EDITOR_THEME_CLASS);
|
|
@@ -982,6 +1233,359 @@ function renderPerformanceMonitorOverlay(overlay, stats, open) {
|
|
|
982
1233
|
stats?.activeReasons.length ? `active: ${stats.activeReasons.join(', ')}` : '',
|
|
983
1234
|
].filter(Boolean).join(' | ');
|
|
984
1235
|
}
|
|
1236
|
+
function createPrefabImportStatsOverlay(doc) {
|
|
1237
|
+
const root = doc.createElement('section');
|
|
1238
|
+
root.classList.add(LOCAL_EDITOR_THEME_CLASS);
|
|
1239
|
+
root.dataset.editorPrefabImportStatsOverlay = 'true';
|
|
1240
|
+
root.setAttribute('aria-label', 'Prefab import diagnostics');
|
|
1241
|
+
root.style.cssText = [
|
|
1242
|
+
'display:none',
|
|
1243
|
+
'width:236px',
|
|
1244
|
+
'max-width:100%',
|
|
1245
|
+
'box-sizing:border-box',
|
|
1246
|
+
'padding:10px',
|
|
1247
|
+
'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
|
|
1248
|
+
'border-radius:6px',
|
|
1249
|
+
'background:color-mix(in srgb, var(--fps-editor-chrome) 88%, transparent)',
|
|
1250
|
+
'box-shadow:var(--fps-editor-shadow-panel)',
|
|
1251
|
+
'backdrop-filter:blur(6px)',
|
|
1252
|
+
'font-family:var(--fps-editor-font)',
|
|
1253
|
+
'font-size:11px',
|
|
1254
|
+
'font-weight:800',
|
|
1255
|
+
'color:var(--fps-editor-text)',
|
|
1256
|
+
'pointer-events:auto',
|
|
1257
|
+
].join(';');
|
|
1258
|
+
const header = doc.createElement('div');
|
|
1259
|
+
header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;';
|
|
1260
|
+
const title = doc.createElement('div');
|
|
1261
|
+
title.textContent = 'Prefab Import';
|
|
1262
|
+
title.style.cssText = 'min-width:0;color:var(--fps-editor-text-strong);font-size:12px;font-weight:900;line-height:1.2;';
|
|
1263
|
+
const modeLabel = doc.createElement('span');
|
|
1264
|
+
modeLabel.textContent = 'MISSING';
|
|
1265
|
+
modeLabel.style.cssText = [
|
|
1266
|
+
'flex:0 0 auto',
|
|
1267
|
+
'padding:2px 5px',
|
|
1268
|
+
'border:1px solid var(--fps-editor-border-soft)',
|
|
1269
|
+
'border-radius:4px',
|
|
1270
|
+
'background:color-mix(in srgb, var(--fps-editor-field) 72%, transparent)',
|
|
1271
|
+
'color:var(--fps-editor-muted)',
|
|
1272
|
+
'font-size:9px',
|
|
1273
|
+
'line-height:1',
|
|
1274
|
+
'font-weight:900',
|
|
1275
|
+
].join(';');
|
|
1276
|
+
header.append(title, modeLabel);
|
|
1277
|
+
const grid = doc.createElement('div');
|
|
1278
|
+
grid.style.cssText = [
|
|
1279
|
+
'display:grid',
|
|
1280
|
+
'grid-template-columns:minmax(0,1fr) minmax(76px,108px)',
|
|
1281
|
+
'gap:5px 10px',
|
|
1282
|
+
'align-items:center',
|
|
1283
|
+
].join(';');
|
|
1284
|
+
const values = {};
|
|
1285
|
+
for (const metric of PREFAB_IMPORT_STATS_METRICS) {
|
|
1286
|
+
const rowLabel = doc.createElement('span');
|
|
1287
|
+
rowLabel.textContent = metric.label;
|
|
1288
|
+
rowLabel.title = metric.description;
|
|
1289
|
+
rowLabel.setAttribute('aria-label', `${metric.label}: ${metric.description}`);
|
|
1290
|
+
rowLabel.style.cssText = [
|
|
1291
|
+
'min-width:0',
|
|
1292
|
+
'overflow:hidden',
|
|
1293
|
+
'text-overflow:ellipsis',
|
|
1294
|
+
'white-space:nowrap',
|
|
1295
|
+
'color:var(--fps-editor-muted-strong)',
|
|
1296
|
+
'cursor:help',
|
|
1297
|
+
].join(';');
|
|
1298
|
+
const value = doc.createElement('span');
|
|
1299
|
+
value.textContent = '--';
|
|
1300
|
+
value.title = metric.description;
|
|
1301
|
+
value.setAttribute('aria-label', `${metric.label}: --。${metric.description}`);
|
|
1302
|
+
value.style.cssText = [
|
|
1303
|
+
'min-width:0',
|
|
1304
|
+
'justify-self:end',
|
|
1305
|
+
'max-width:108px',
|
|
1306
|
+
'overflow:hidden',
|
|
1307
|
+
'text-overflow:ellipsis',
|
|
1308
|
+
'white-space:nowrap',
|
|
1309
|
+
'font-variant-numeric:tabular-nums',
|
|
1310
|
+
'color:var(--fps-editor-text-strong)',
|
|
1311
|
+
'text-align:right',
|
|
1312
|
+
'cursor:help',
|
|
1313
|
+
].join(';');
|
|
1314
|
+
values[metric.key] = value;
|
|
1315
|
+
grid.append(rowLabel, value);
|
|
1316
|
+
}
|
|
1317
|
+
root.append(header, grid);
|
|
1318
|
+
return { root, modeLabel, values };
|
|
1319
|
+
}
|
|
1320
|
+
function renderPrefabImportStatsOverlay(overlay, stage) {
|
|
1321
|
+
if (!stage) {
|
|
1322
|
+
overlay.root.style.display = 'none';
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
overlay.root.style.display = 'block';
|
|
1326
|
+
const stats = stage.importStats ?? null;
|
|
1327
|
+
const status = stats?.status ?? (stage.importStructureReady === false ? 'loading' : 'missing');
|
|
1328
|
+
overlay.modeLabel.textContent = formatPrefabImportStatsStatusLabel(status);
|
|
1329
|
+
overlay.modeLabel.style.color = status === 'ready'
|
|
1330
|
+
? 'var(--fps-editor-success)'
|
|
1331
|
+
: status === 'loading'
|
|
1332
|
+
? 'var(--fps-editor-warn)'
|
|
1333
|
+
: 'var(--fps-editor-danger-strong)';
|
|
1334
|
+
for (const metric of PREFAB_IMPORT_STATS_METRICS) {
|
|
1335
|
+
const value = metric.format(stats);
|
|
1336
|
+
overlay.values[metric.key].textContent = value;
|
|
1337
|
+
overlay.values[metric.key].title = `${metric.description}\n${value}`;
|
|
1338
|
+
overlay.values[metric.key].setAttribute('aria-label', `${metric.label}: ${value}。${metric.description}`);
|
|
1339
|
+
}
|
|
1340
|
+
overlay.root.title = [
|
|
1341
|
+
`status: ${status}`,
|
|
1342
|
+
stats?.projectionNodeId ? `preview: ${stats.projectionNodeId}` : stage.previewNodeId ? `preview: ${stage.previewNodeId}` : '',
|
|
1343
|
+
stats?.assetId ? `asset: ${stats.assetId}` : '',
|
|
1344
|
+
stats?.sourceId ? `source: ${stats.sourceId}` : '',
|
|
1345
|
+
].filter(Boolean).join(' | ');
|
|
1346
|
+
}
|
|
1347
|
+
function createPrefabStagePreviewLayout(doc) {
|
|
1348
|
+
const root = doc.createElement('section');
|
|
1349
|
+
root.classList.add(LOCAL_EDITOR_THEME_CLASS);
|
|
1350
|
+
root.dataset.editorPrefabStagePreviewLayout = 'true';
|
|
1351
|
+
root.setAttribute('aria-label', 'Prefab stage preview layout');
|
|
1352
|
+
root.style.cssText = [
|
|
1353
|
+
'position:absolute',
|
|
1354
|
+
'left:0',
|
|
1355
|
+
'right:0',
|
|
1356
|
+
'top:38px',
|
|
1357
|
+
'bottom:0',
|
|
1358
|
+
'z-index:4',
|
|
1359
|
+
'display:none',
|
|
1360
|
+
'pointer-events:none',
|
|
1361
|
+
'overflow:hidden',
|
|
1362
|
+
'font-family:var(--fps-editor-font)',
|
|
1363
|
+
].join(';');
|
|
1364
|
+
const mainRegion = doc.createElement('div');
|
|
1365
|
+
mainRegion.dataset.editorPrefabStageMainPreview = 'true';
|
|
1366
|
+
mainRegion.style.cssText = [
|
|
1367
|
+
'position:absolute',
|
|
1368
|
+
'left:0',
|
|
1369
|
+
'top:0',
|
|
1370
|
+
'bottom:0',
|
|
1371
|
+
'right:0',
|
|
1372
|
+
'min-width:0',
|
|
1373
|
+
'overflow:hidden',
|
|
1374
|
+
'pointer-events:none',
|
|
1375
|
+
].join(';');
|
|
1376
|
+
const comparisonColumn = doc.createElement('aside');
|
|
1377
|
+
comparisonColumn.dataset.editorPrefabStageComparisonColumn = 'true';
|
|
1378
|
+
comparisonColumn.setAttribute('aria-label', 'Prefab comparison previews');
|
|
1379
|
+
comparisonColumn.style.cssText = [
|
|
1380
|
+
'position:absolute',
|
|
1381
|
+
'top:0',
|
|
1382
|
+
'right:0',
|
|
1383
|
+
'bottom:0',
|
|
1384
|
+
`width:${LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX}px`,
|
|
1385
|
+
'display:none',
|
|
1386
|
+
'flex-direction:column',
|
|
1387
|
+
'box-sizing:border-box',
|
|
1388
|
+
'gap:10px',
|
|
1389
|
+
'padding:10px',
|
|
1390
|
+
'border-left:1px solid color-mix(in srgb, var(--fps-editor-divider) 82%, transparent)',
|
|
1391
|
+
'background:transparent',
|
|
1392
|
+
'box-shadow:none',
|
|
1393
|
+
'pointer-events:auto',
|
|
1394
|
+
'overflow:hidden',
|
|
1395
|
+
].join(';');
|
|
1396
|
+
root.append(mainRegion, comparisonColumn);
|
|
1397
|
+
return { root, mainRegion, comparisonColumn };
|
|
1398
|
+
}
|
|
1399
|
+
function createPrefabComparisonPreviewOverlay(doc) {
|
|
1400
|
+
const root = doc.createElement('section');
|
|
1401
|
+
root.classList.add(LOCAL_EDITOR_THEME_CLASS);
|
|
1402
|
+
root.dataset.editorPrefabComparisonPreviewOverlay = 'true';
|
|
1403
|
+
root.setAttribute('aria-label', 'Prefab clone and InstanceMesh comparison previews');
|
|
1404
|
+
root.style.cssText = [
|
|
1405
|
+
'display:none',
|
|
1406
|
+
'flex:1 1 auto',
|
|
1407
|
+
'min-height:0',
|
|
1408
|
+
'width:100%',
|
|
1409
|
+
'box-sizing:border-box',
|
|
1410
|
+
'grid-template-rows:minmax(0,1fr) minmax(0,1fr)',
|
|
1411
|
+
'gap:10px',
|
|
1412
|
+
'overflow:hidden',
|
|
1413
|
+
'font-family:var(--fps-editor-font)',
|
|
1414
|
+
'pointer-events:auto',
|
|
1415
|
+
].join(';');
|
|
1416
|
+
return { root, cards: new Map() };
|
|
1417
|
+
}
|
|
1418
|
+
function renderPrefabComparisonPreviewOverlay(overlay, stage) {
|
|
1419
|
+
const previews = stage?.comparisonPreviews ?? [];
|
|
1420
|
+
if (!stage || previews.length === 0) {
|
|
1421
|
+
overlay.root.style.display = 'none';
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
overlay.root.style.display = 'grid';
|
|
1425
|
+
const visibleIds = new Set();
|
|
1426
|
+
for (const preview of previews) {
|
|
1427
|
+
const card = getOrCreatePrefabComparisonPreviewCard(overlay, preview);
|
|
1428
|
+
visibleIds.add(preview.id);
|
|
1429
|
+
card.root.style.display = 'flex';
|
|
1430
|
+
card.title.textContent = preview.label;
|
|
1431
|
+
card.statusLabel.textContent = formatLocalEditorPrefabStageComparisonPreviewStatus(preview.status);
|
|
1432
|
+
card.statusLabel.style.color = getPrefabComparisonPreviewStatusColor(preview.status);
|
|
1433
|
+
card.surface.dataset.editorPrefabComparisonPreviewId = preview.id;
|
|
1434
|
+
card.surface.dataset.editorPrefabComparisonPreviewSurface = preview.projectionNodeId;
|
|
1435
|
+
card.surface.dataset.editorPrefabComparisonPreviewStatus = preview.status;
|
|
1436
|
+
card.surface.style.background = preview.status === 'ready'
|
|
1437
|
+
? 'transparent'
|
|
1438
|
+
: 'color-mix(in srgb, var(--fps-editor-field) 74%, transparent)';
|
|
1439
|
+
card.surface.textContent = preview.status === 'ready'
|
|
1440
|
+
? ''
|
|
1441
|
+
: preview.status === 'loading'
|
|
1442
|
+
? 'Preview loading'
|
|
1443
|
+
: 'Preview unavailable';
|
|
1444
|
+
card.root.title = [
|
|
1445
|
+
`${preview.label}: ${preview.status}`,
|
|
1446
|
+
`mode: ${preview.mode}`,
|
|
1447
|
+
`projection: ${preview.projectionNodeId}`,
|
|
1448
|
+
].join(' | ');
|
|
1449
|
+
}
|
|
1450
|
+
for (const [id, card] of overlay.cards) {
|
|
1451
|
+
if (!visibleIds.has(id))
|
|
1452
|
+
card.root.style.display = 'none';
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
function readPrefabComparisonPreviewSurfaces(overlay) {
|
|
1456
|
+
if (overlay.root.style.display === 'none')
|
|
1457
|
+
return [];
|
|
1458
|
+
const surfaces = [];
|
|
1459
|
+
for (const [previewId, card] of overlay.cards) {
|
|
1460
|
+
if (card.root.style.display === 'none')
|
|
1461
|
+
continue;
|
|
1462
|
+
const projectionNodeId = card.surface.dataset.editorPrefabComparisonPreviewSurface;
|
|
1463
|
+
if (!projectionNodeId)
|
|
1464
|
+
continue;
|
|
1465
|
+
const rect = card.surface.getBoundingClientRect();
|
|
1466
|
+
if (rect.width < 1 || rect.height < 1)
|
|
1467
|
+
continue;
|
|
1468
|
+
surfaces.push({
|
|
1469
|
+
previewId,
|
|
1470
|
+
projectionNodeId,
|
|
1471
|
+
element: card.surface,
|
|
1472
|
+
rect,
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
return surfaces;
|
|
1476
|
+
}
|
|
1477
|
+
function findPrefabComparisonPreviewSurface(target) {
|
|
1478
|
+
return target instanceof HTMLElement
|
|
1479
|
+
? target.closest('[data-editor-prefab-comparison-preview-surface]')
|
|
1480
|
+
: null;
|
|
1481
|
+
}
|
|
1482
|
+
function readPrefabComparisonPreviewSurfaceId(surface) {
|
|
1483
|
+
return surface.dataset.editorPrefabComparisonPreviewId
|
|
1484
|
+
?? surface.closest('[data-editor-prefab-comparison-preview]')?.dataset.editorPrefabComparisonPreview
|
|
1485
|
+
?? null;
|
|
1486
|
+
}
|
|
1487
|
+
function isPrefabComparisonPreviewSurfaceReady(surface) {
|
|
1488
|
+
return surface.dataset.editorPrefabComparisonPreviewStatus === 'ready';
|
|
1489
|
+
}
|
|
1490
|
+
function getOrCreatePrefabComparisonPreviewCard(overlay, preview) {
|
|
1491
|
+
const existing = overlay.cards.get(preview.id);
|
|
1492
|
+
if (existing)
|
|
1493
|
+
return existing;
|
|
1494
|
+
const doc = overlay.root.ownerDocument;
|
|
1495
|
+
const root = doc.createElement('article');
|
|
1496
|
+
root.dataset.editorPrefabComparisonPreview = preview.id;
|
|
1497
|
+
root.style.cssText = [
|
|
1498
|
+
'display:flex',
|
|
1499
|
+
'flex-direction:column',
|
|
1500
|
+
'min-width:0',
|
|
1501
|
+
'min-height:0',
|
|
1502
|
+
'flex:1 1 0',
|
|
1503
|
+
'box-sizing:border-box',
|
|
1504
|
+
'padding:8px',
|
|
1505
|
+
'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
|
|
1506
|
+
'border-radius:6px',
|
|
1507
|
+
'background:transparent',
|
|
1508
|
+
'box-shadow:none',
|
|
1509
|
+
'color:var(--fps-editor-text)',
|
|
1510
|
+
'pointer-events:auto',
|
|
1511
|
+
'overflow:hidden',
|
|
1512
|
+
].join(';');
|
|
1513
|
+
const header = doc.createElement('div');
|
|
1514
|
+
header.style.cssText = [
|
|
1515
|
+
'display:flex',
|
|
1516
|
+
'align-items:center',
|
|
1517
|
+
'justify-content:space-between',
|
|
1518
|
+
'gap:8px',
|
|
1519
|
+
'margin-bottom:7px',
|
|
1520
|
+
'padding:6px 8px',
|
|
1521
|
+
'border:1px solid color-mix(in srgb, var(--fps-editor-border) 74%, transparent)',
|
|
1522
|
+
'border-radius:5px',
|
|
1523
|
+
'background:color-mix(in srgb, var(--fps-editor-chrome) 86%, transparent)',
|
|
1524
|
+
'box-shadow:0 6px 14px color-mix(in srgb, #000 18%, transparent)',
|
|
1525
|
+
].join(';');
|
|
1526
|
+
const title = doc.createElement('div');
|
|
1527
|
+
title.textContent = preview.label;
|
|
1528
|
+
title.style.cssText = [
|
|
1529
|
+
'min-width:0',
|
|
1530
|
+
'overflow:hidden',
|
|
1531
|
+
'text-overflow:ellipsis',
|
|
1532
|
+
'white-space:nowrap',
|
|
1533
|
+
'color:var(--fps-editor-text-strong)',
|
|
1534
|
+
'font-size:12px',
|
|
1535
|
+
'line-height:1.2',
|
|
1536
|
+
'font-weight:900',
|
|
1537
|
+
].join(';');
|
|
1538
|
+
const statusLabel = doc.createElement('span');
|
|
1539
|
+
statusLabel.textContent = 'UNAVAILABLE';
|
|
1540
|
+
statusLabel.style.cssText = [
|
|
1541
|
+
'flex:0 0 auto',
|
|
1542
|
+
'padding:2px 5px',
|
|
1543
|
+
'border:1px solid var(--fps-editor-border-soft)',
|
|
1544
|
+
'border-radius:4px',
|
|
1545
|
+
'background:color-mix(in srgb, var(--fps-editor-field) 72%, transparent)',
|
|
1546
|
+
'font-size:9px',
|
|
1547
|
+
'line-height:1',
|
|
1548
|
+
'font-weight:900',
|
|
1549
|
+
].join(';');
|
|
1550
|
+
header.append(title, statusLabel);
|
|
1551
|
+
const surface = doc.createElement('div');
|
|
1552
|
+
surface.style.cssText = [
|
|
1553
|
+
'display:flex',
|
|
1554
|
+
'flex:1 1 auto',
|
|
1555
|
+
'align-items:center',
|
|
1556
|
+
'justify-content:center',
|
|
1557
|
+
'width:100%',
|
|
1558
|
+
'min-height:0',
|
|
1559
|
+
'box-sizing:border-box',
|
|
1560
|
+
'border:1px solid color-mix(in srgb, var(--fps-editor-border-soft) 84%, transparent)',
|
|
1561
|
+
'border-radius:4px',
|
|
1562
|
+
'background:transparent',
|
|
1563
|
+
'overflow:hidden',
|
|
1564
|
+
'color:var(--fps-editor-muted)',
|
|
1565
|
+
'font-size:10px',
|
|
1566
|
+
'font-weight:800',
|
|
1567
|
+
'text-align:center',
|
|
1568
|
+
'touch-action:none',
|
|
1569
|
+
'user-select:none',
|
|
1570
|
+
'cursor:grab',
|
|
1571
|
+
].join(';');
|
|
1572
|
+
root.append(header, surface);
|
|
1573
|
+
overlay.root.appendChild(root);
|
|
1574
|
+
const card = { root, title, statusLabel, surface };
|
|
1575
|
+
overlay.cards.set(preview.id, card);
|
|
1576
|
+
return card;
|
|
1577
|
+
}
|
|
1578
|
+
function getPrefabComparisonPreviewStatusColor(status) {
|
|
1579
|
+
const tone = resolveLocalEditorPrefabStageComparisonPreviewTone(status);
|
|
1580
|
+
return tone === 'success'
|
|
1581
|
+
? 'var(--fps-editor-success)'
|
|
1582
|
+
: tone === 'warning'
|
|
1583
|
+
? 'var(--fps-editor-warn)'
|
|
1584
|
+
: 'var(--fps-editor-danger-strong)';
|
|
1585
|
+
}
|
|
1586
|
+
function formatPrefabImportStatsStatusLabel(status) {
|
|
1587
|
+
return status === 'ready' ? 'READY' : status === 'loading' ? 'LOADING' : 'MISSING';
|
|
1588
|
+
}
|
|
985
1589
|
function formatPerformanceInteger(value) {
|
|
986
1590
|
return typeof value === 'number' && Number.isFinite(value) ? String(Math.round(value)) : '--';
|
|
987
1591
|
}
|
|
@@ -1413,10 +2017,10 @@ function formatSvgNumber(value) {
|
|
|
1413
2017
|
return Number.isFinite(value) ? value.toFixed(2) : '0';
|
|
1414
2018
|
}
|
|
1415
2019
|
function isLocalEditorAssetBrowserTab(value) {
|
|
1416
|
-
return value === 'all' || value === 'models' || value === 'materials' || value === 'textures';
|
|
2020
|
+
return value === 'all' || value === 'models' || value === 'prefabs' || value === 'materials' || value === 'textures';
|
|
1417
2021
|
}
|
|
1418
|
-
function createAssetBrowserMenuItems(state, asset) {
|
|
1419
|
-
const assetKind =
|
|
2022
|
+
export function createAssetBrowserMenuItems(state, asset) {
|
|
2023
|
+
const assetKind = resolveLocalEditorBrowserAssetKind(asset);
|
|
1420
2024
|
const placeable = asset.placeable !== false && asset.disabled !== true;
|
|
1421
2025
|
const activeId = state.activeId;
|
|
1422
2026
|
const items = [];
|
|
@@ -1449,6 +2053,20 @@ function createAssetBrowserMenuItems(state, asset) {
|
|
|
1449
2053
|
label: '查看贴图预览',
|
|
1450
2054
|
});
|
|
1451
2055
|
}
|
|
2056
|
+
else if (assetKind === 'prefab') {
|
|
2057
|
+
items.push({
|
|
2058
|
+
id: 'asset.edit-prefab',
|
|
2059
|
+
label: '编辑 Prefab',
|
|
2060
|
+
disabled: !asset.prefab,
|
|
2061
|
+
disabledReason: '该预制体资产缺少可编辑参数。',
|
|
2062
|
+
});
|
|
2063
|
+
items.push({
|
|
2064
|
+
id: 'asset.duplicate-prefab',
|
|
2065
|
+
label: '复制 Prefab',
|
|
2066
|
+
disabled: !asset.assetId && !asset.id,
|
|
2067
|
+
disabledReason: '该预制体资产缺少可复制的 Prefab ID。',
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
1452
2070
|
if (assetKind === 'material') {
|
|
1453
2071
|
items.push({
|
|
1454
2072
|
id: 'asset.apply-material',
|
|
@@ -1486,6 +2104,21 @@ function createAssetBrowserMenuItems(state, asset) {
|
|
|
1486
2104
|
disabledReason: '自发光遮罩绑定将在下一步接入。',
|
|
1487
2105
|
});
|
|
1488
2106
|
}
|
|
2107
|
+
else if (assetKind === 'prefab') {
|
|
2108
|
+
items.push({
|
|
2109
|
+
id: 'asset.add-to-scene',
|
|
2110
|
+
label: '添加 Prefab 到场景',
|
|
2111
|
+
separatorBefore: true,
|
|
2112
|
+
disabled: !placeable,
|
|
2113
|
+
disabledReason: '该 Prefab 当前不可放置。',
|
|
2114
|
+
});
|
|
2115
|
+
items.push({
|
|
2116
|
+
id: 'asset.place',
|
|
2117
|
+
label: '进入 Prefab 放置模式',
|
|
2118
|
+
disabled: !placeable,
|
|
2119
|
+
disabledReason: '该 Prefab 当前不可放置。',
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
1489
2122
|
else {
|
|
1490
2123
|
items.push({
|
|
1491
2124
|
id: 'asset.add-to-scene',
|
|
@@ -1499,12 +2132,18 @@ function createAssetBrowserMenuItems(state, asset) {
|
|
|
1499
2132
|
disabled: !placeable,
|
|
1500
2133
|
disabledReason: '该模型当前不可放置。',
|
|
1501
2134
|
});
|
|
2135
|
+
items.push({
|
|
2136
|
+
id: 'asset.create-prefab',
|
|
2137
|
+
label: '创建 Prefab',
|
|
2138
|
+
disabled: !asset.assetId && !asset.id,
|
|
2139
|
+
disabledReason: '该模型缺少可创建 Prefab 的 Asset ID。',
|
|
2140
|
+
separatorBefore: true,
|
|
2141
|
+
});
|
|
1502
2142
|
items.push({
|
|
1503
2143
|
id: 'asset.add-as-child',
|
|
1504
2144
|
label: '添加为当前节点子对象',
|
|
1505
2145
|
disabled: true,
|
|
1506
2146
|
disabledReason: '子对象添加动作将在资产 patch 中接入。',
|
|
1507
|
-
separatorBefore: true,
|
|
1508
2147
|
});
|
|
1509
2148
|
items.push({
|
|
1510
2149
|
id: 'asset.replace-selected-model',
|
|
@@ -1532,22 +2171,12 @@ function getMaterialAssetDeleteDisabledReason(asset) {
|
|
|
1532
2171
|
return `该材质正在被 ${usageCount} 处使用,请先替换或解绑。`;
|
|
1533
2172
|
return undefined;
|
|
1534
2173
|
}
|
|
1535
|
-
function resolveBrowserAssetKind(asset) {
|
|
1536
|
-
const kind = `${asset.kind ?? ''}`.trim().toLowerCase();
|
|
1537
|
-
const id = `${asset.id ?? ''}`.trim().toLowerCase();
|
|
1538
|
-
const assetId = `${asset.assetId ?? ''}`.trim().toLowerCase();
|
|
1539
|
-
if (kind === 'material' || id.startsWith('material:') || assetId.startsWith('mat_'))
|
|
1540
|
-
return 'material';
|
|
1541
|
-
if (kind === 'texture' || kind === 'image' || id.startsWith('texture:') || assetId.startsWith('texture_'))
|
|
1542
|
-
return 'texture';
|
|
1543
|
-
return 'model';
|
|
1544
|
-
}
|
|
1545
2174
|
function createAssetBrowserActionInput(actionId, asset) {
|
|
1546
2175
|
return {
|
|
1547
2176
|
actionId,
|
|
1548
2177
|
assetId: asset.assetId ?? asset.id,
|
|
1549
2178
|
browserAssetId: asset.id,
|
|
1550
|
-
assetKind: asset.kind,
|
|
2179
|
+
assetKind: asset.kind ?? resolveLocalEditorBrowserAssetKind(asset),
|
|
1551
2180
|
};
|
|
1552
2181
|
}
|
|
1553
2182
|
function copyTextToClipboard(win, text) {
|
|
@@ -1755,6 +2384,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
1755
2384
|
const redoButton = createToolbarIconButton(doc, '重做', 'redo', '重做');
|
|
1756
2385
|
let helpOpen = false;
|
|
1757
2386
|
let performanceMonitorOpen = false;
|
|
2387
|
+
let prefabComparisonPreviewOpen = true;
|
|
1758
2388
|
let assetPreviewOpen = false;
|
|
1759
2389
|
let previewedAsset = null;
|
|
1760
2390
|
let assetPreviewMode = 'preview';
|
|
@@ -1762,6 +2392,8 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
1762
2392
|
let assetPickerFilter = '';
|
|
1763
2393
|
let assetPickerInput = null;
|
|
1764
2394
|
let assetPickerProperty = null;
|
|
2395
|
+
let prefabStageExplorerFilter = '';
|
|
2396
|
+
let prefabComparisonPreviewDrag = null;
|
|
1765
2397
|
const editorStatusButton = createToolbarIconButton(doc, '编辑器状态', 'status', '编辑器状态');
|
|
1766
2398
|
editorStatusButton.dataset.editorStatusButton = 'true';
|
|
1767
2399
|
editorStatusButton.style.cursor = 'help';
|
|
@@ -1772,14 +2404,22 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
1772
2404
|
const rightDockTabs = doc.createElement('div');
|
|
1773
2405
|
const inspectorPanel = createWorkbenchPanelContent(doc);
|
|
1774
2406
|
const renderingPanel = createWorkbenchPanelContent(doc);
|
|
2407
|
+
const markersPanel = createWorkbenchPanelContent(doc);
|
|
1775
2408
|
workbench.leftDock.appendChild(leftDockTabs);
|
|
1776
2409
|
workbench.leftDock.appendChild(hierarchyPanel);
|
|
1777
2410
|
workbench.rightDock.appendChild(rightDockTabs);
|
|
1778
2411
|
workbench.rightDock.appendChild(inspectorPanel);
|
|
1779
2412
|
workbench.rightDock.appendChild(renderingPanel);
|
|
2413
|
+
workbench.rightDock.appendChild(markersPanel);
|
|
1780
2414
|
root.appendChild(workbench.root);
|
|
1781
2415
|
tooltipSurfaces.add(workbench.root);
|
|
1782
|
-
const workbenchLayoutController = createLocalEditorWorkbenchLayoutController(doc, workbench
|
|
2416
|
+
const workbenchLayoutController = createLocalEditorWorkbenchLayoutController(doc, workbench, {
|
|
2417
|
+
onAfterApply(layout) {
|
|
2418
|
+
if (currentState?.mode === 'editor' && currentState.prefabStage) {
|
|
2419
|
+
applyPrefabStageWorkbenchLayoutOverride(layout);
|
|
2420
|
+
}
|
|
2421
|
+
},
|
|
2422
|
+
});
|
|
1783
2423
|
const findAssetBrowserScrollViewport = () => (assetPanel.querySelector('[data-editor-asset-browser-scroll-viewport]'));
|
|
1784
2424
|
const assetBrowserViewportReveal = createLocalEditorViewportRevealController({
|
|
1785
2425
|
getViewport: findAssetBrowserScrollViewport,
|
|
@@ -2152,13 +2792,20 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
2152
2792
|
performanceMonitorButton.dataset.performanceMonitorToggle = 'true';
|
|
2153
2793
|
const gridToggleButton = createToolbarIconButton(doc, '网格', 'grid', '显示 / 隐藏 Scene View 网格');
|
|
2154
2794
|
gridToggleButton.dataset.editorGridToggle = 'true';
|
|
2795
|
+
const prefabComparisonPreviewButton = createToolbarIconButton(doc, '对比预览', 'eye', 'Compare Previews (Shift+P)', 'toggle');
|
|
2796
|
+
prefabComparisonPreviewButton.dataset.prefabComparisonPreviewToggle = 'true';
|
|
2155
2797
|
const sceneHelpButton = createToolbarIconButton(doc, '快捷键', 'help', '快捷键与操作说明');
|
|
2156
2798
|
sceneQuickActions.appendChild(localTestGroup);
|
|
2799
|
+
const prefabStageBackButton = createToolbarIconButton(doc, '返回场景', 'chevron-right', '返回主场景');
|
|
2800
|
+
prefabStageBackButton.dataset.editorPrefabStageBack = 'true';
|
|
2801
|
+
prefabStageBackButton.style.display = 'none';
|
|
2802
|
+
sceneQuickActions.appendChild(prefabStageBackButton);
|
|
2157
2803
|
sceneQuickActions.appendChild(undoButton);
|
|
2158
2804
|
sceneQuickActions.appendChild(redoButton);
|
|
2159
2805
|
sceneQuickActions.appendChild(dirtyBadge);
|
|
2160
2806
|
sceneUtilityActions.appendChild(performanceMonitorButton);
|
|
2161
2807
|
sceneUtilityActions.appendChild(gridToggleButton);
|
|
2808
|
+
sceneUtilityActions.appendChild(prefabComparisonPreviewButton);
|
|
2162
2809
|
sceneUtilityActions.appendChild(themeToggleButton);
|
|
2163
2810
|
sceneUtilityActions.appendChild(sceneHelpButton);
|
|
2164
2811
|
const cameraPreviewGroup = doc.createElement('div');
|
|
@@ -2190,6 +2837,9 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
2190
2837
|
const projectionToggleButton = createToolbarIconButton(doc, '投影模式', 'projection-perspective', '切换投影模式');
|
|
2191
2838
|
projectionToggleButton.dataset.viewportProjectionToggle = 'true';
|
|
2192
2839
|
viewportToolsGroup.appendChild(projectionToggleButton);
|
|
2840
|
+
const markerVisibilityButton = createToolbarIconButton(doc, '标记视图', 'view-overlay', '隐藏标记与关系线', 'toggle');
|
|
2841
|
+
markerVisibilityButton.dataset.viewportMarkerVisibilityToggle = 'true';
|
|
2842
|
+
viewportToolsGroup.appendChild(markerVisibilityButton);
|
|
2193
2843
|
const overlaySettingsButton = createToolbarIconButton(doc, '视口信息层设置', 'view-overlay', '视口信息层设置', 'settings');
|
|
2194
2844
|
overlaySettingsButton.dataset.viewportOverlaySettingsToggle = 'true';
|
|
2195
2845
|
viewportToolsGroup.appendChild(overlaySettingsButton);
|
|
@@ -2266,6 +2916,112 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
2266
2916
|
const coordinateAxesOverlay = createCoordinateAxesOverlay(doc);
|
|
2267
2917
|
const sceneFrameRateOverlay = createSceneFrameRateOverlay(doc);
|
|
2268
2918
|
const performanceMonitorOverlay = createPerformanceMonitorOverlay(doc);
|
|
2919
|
+
const prefabImportStatsOverlay = createPrefabImportStatsOverlay(doc);
|
|
2920
|
+
const prefabComparisonPreviewOverlay = createPrefabComparisonPreviewOverlay(doc);
|
|
2921
|
+
const prefabStagePreviewLayout = createPrefabStagePreviewLayout(doc);
|
|
2922
|
+
prefabImportStatsOverlay.root.style.position = 'absolute';
|
|
2923
|
+
prefabImportStatsOverlay.root.style.top = '10px';
|
|
2924
|
+
prefabImportStatsOverlay.root.style.right = '14px';
|
|
2925
|
+
prefabComparisonPreviewOverlay.root.style.height = '100%';
|
|
2926
|
+
prefabStagePreviewLayout.mainRegion.appendChild(prefabImportStatsOverlay.root);
|
|
2927
|
+
prefabStagePreviewLayout.comparisonColumn.appendChild(prefabComparisonPreviewOverlay.root);
|
|
2928
|
+
const emitPrefabComparisonPreviewInteraction = (input) => {
|
|
2929
|
+
if (currentState?.mode !== 'editor' || !currentState.prefabStage)
|
|
2930
|
+
return;
|
|
2931
|
+
callbacks.onPrefabComparisonPreviewInteraction?.(input);
|
|
2932
|
+
};
|
|
2933
|
+
const endPrefabComparisonPreviewDrag = (pointerId) => {
|
|
2934
|
+
const drag = prefabComparisonPreviewDrag;
|
|
2935
|
+
if (!drag || (pointerId != null && drag.pointerId !== pointerId))
|
|
2936
|
+
return;
|
|
2937
|
+
try {
|
|
2938
|
+
if (!drag.surface.hasPointerCapture || drag.surface.hasPointerCapture(drag.pointerId)) {
|
|
2939
|
+
drag.surface.releasePointerCapture?.(drag.pointerId);
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
catch {
|
|
2943
|
+
// Pointer capture may already be released by the browser when this cleanup runs.
|
|
2944
|
+
}
|
|
2945
|
+
drag.surface.style.cursor = 'grab';
|
|
2946
|
+
prefabComparisonPreviewDrag = null;
|
|
2947
|
+
};
|
|
2948
|
+
const onPrefabComparisonPreviewPointerDown = (event) => {
|
|
2949
|
+
if (event.button !== 0 || currentState?.mode !== 'editor' || !currentState.prefabStage)
|
|
2950
|
+
return;
|
|
2951
|
+
const surface = findPrefabComparisonPreviewSurface(event.target);
|
|
2952
|
+
if (!surface || !isPrefabComparisonPreviewSurfaceReady(surface))
|
|
2953
|
+
return;
|
|
2954
|
+
const previewId = readPrefabComparisonPreviewSurfaceId(surface);
|
|
2955
|
+
if (!previewId)
|
|
2956
|
+
return;
|
|
2957
|
+
event.preventDefault();
|
|
2958
|
+
event.stopPropagation();
|
|
2959
|
+
endPrefabComparisonPreviewDrag();
|
|
2960
|
+
try {
|
|
2961
|
+
surface.setPointerCapture?.(event.pointerId);
|
|
2962
|
+
}
|
|
2963
|
+
catch {
|
|
2964
|
+
// Pointer capture is an input nicety; drag state still works through the overlay listener.
|
|
2965
|
+
}
|
|
2966
|
+
surface.style.cursor = 'grabbing';
|
|
2967
|
+
prefabComparisonPreviewDrag = {
|
|
2968
|
+
pointerId: event.pointerId,
|
|
2969
|
+
previewId,
|
|
2970
|
+
surface,
|
|
2971
|
+
lastClientX: event.clientX,
|
|
2972
|
+
lastClientY: event.clientY,
|
|
2973
|
+
};
|
|
2974
|
+
};
|
|
2975
|
+
const onPrefabComparisonPreviewPointerMove = (event) => {
|
|
2976
|
+
const drag = prefabComparisonPreviewDrag;
|
|
2977
|
+
if (!drag || drag.pointerId !== event.pointerId)
|
|
2978
|
+
return;
|
|
2979
|
+
event.preventDefault();
|
|
2980
|
+
event.stopPropagation();
|
|
2981
|
+
const deltaX = event.clientX - drag.lastClientX;
|
|
2982
|
+
const deltaY = event.clientY - drag.lastClientY;
|
|
2983
|
+
drag.lastClientX = event.clientX;
|
|
2984
|
+
drag.lastClientY = event.clientY;
|
|
2985
|
+
if (Math.abs(deltaX) < 0.001 && Math.abs(deltaY) < 0.001)
|
|
2986
|
+
return;
|
|
2987
|
+
emitPrefabComparisonPreviewInteraction({
|
|
2988
|
+
kind: 'orbit',
|
|
2989
|
+
previewId: drag.previewId,
|
|
2990
|
+
deltaX,
|
|
2991
|
+
deltaY,
|
|
2992
|
+
});
|
|
2993
|
+
};
|
|
2994
|
+
const onPrefabComparisonPreviewPointerEnd = (event) => {
|
|
2995
|
+
const drag = prefabComparisonPreviewDrag;
|
|
2996
|
+
if (!drag || drag.pointerId !== event.pointerId)
|
|
2997
|
+
return;
|
|
2998
|
+
event.preventDefault();
|
|
2999
|
+
event.stopPropagation();
|
|
3000
|
+
endPrefabComparisonPreviewDrag(event.pointerId);
|
|
3001
|
+
};
|
|
3002
|
+
const onPrefabComparisonPreviewWheel = (event) => {
|
|
3003
|
+
if (currentState?.mode !== 'editor' || !currentState.prefabStage)
|
|
3004
|
+
return;
|
|
3005
|
+
const surface = findPrefabComparisonPreviewSurface(event.target);
|
|
3006
|
+
if (!surface || !isPrefabComparisonPreviewSurfaceReady(surface))
|
|
3007
|
+
return;
|
|
3008
|
+
const previewId = readPrefabComparisonPreviewSurfaceId(surface);
|
|
3009
|
+
if (!previewId)
|
|
3010
|
+
return;
|
|
3011
|
+
event.preventDefault();
|
|
3012
|
+
event.stopPropagation();
|
|
3013
|
+
emitPrefabComparisonPreviewInteraction({
|
|
3014
|
+
kind: 'zoom',
|
|
3015
|
+
previewId,
|
|
3016
|
+
deltaY: event.deltaY,
|
|
3017
|
+
});
|
|
3018
|
+
};
|
|
3019
|
+
prefabComparisonPreviewOverlay.root.addEventListener('pointerdown', onPrefabComparisonPreviewPointerDown);
|
|
3020
|
+
prefabComparisonPreviewOverlay.root.addEventListener('pointermove', onPrefabComparisonPreviewPointerMove);
|
|
3021
|
+
prefabComparisonPreviewOverlay.root.addEventListener('pointerup', onPrefabComparisonPreviewPointerEnd);
|
|
3022
|
+
prefabComparisonPreviewOverlay.root.addEventListener('pointercancel', onPrefabComparisonPreviewPointerEnd);
|
|
3023
|
+
prefabComparisonPreviewOverlay.root.addEventListener('lostpointercapture', onPrefabComparisonPreviewPointerEnd);
|
|
3024
|
+
prefabComparisonPreviewOverlay.root.addEventListener('wheel', onPrefabComparisonPreviewWheel, { passive: false });
|
|
2269
3025
|
const spatialOverlay = createSpatialOverlay(doc);
|
|
2270
3026
|
const measurementOverlay = createMeasurementOverlay(doc);
|
|
2271
3027
|
sceneToolOverlay.appendChild(sceneTitle);
|
|
@@ -2286,6 +3042,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
2286
3042
|
workbench.sceneFrame.appendChild(measurementOverlay.root);
|
|
2287
3043
|
workbench.sceneFrame.appendChild(sceneFrameRateOverlay.root);
|
|
2288
3044
|
workbench.sceneFrame.appendChild(performanceMonitorOverlay.root);
|
|
3045
|
+
workbench.sceneFrame.appendChild(prefabStagePreviewLayout.root);
|
|
2289
3046
|
workbench.sceneFrame.appendChild(coordinateAxesOverlay.root);
|
|
2290
3047
|
root.appendChild(localTestMenu);
|
|
2291
3048
|
root.appendChild(toolbarOverflowMenu);
|
|
@@ -2483,6 +3240,9 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
2483
3240
|
applyLocalEditorTheme(measurementOverlay.root, activeTheme);
|
|
2484
3241
|
applyLocalEditorTheme(sceneFrameRateOverlay.root, activeTheme);
|
|
2485
3242
|
applyLocalEditorTheme(performanceMonitorOverlay.root, activeTheme);
|
|
3243
|
+
applyLocalEditorTheme(prefabStagePreviewLayout.root, activeTheme);
|
|
3244
|
+
applyLocalEditorTheme(prefabImportStatsOverlay.root, activeTheme);
|
|
3245
|
+
applyLocalEditorTheme(prefabComparisonPreviewOverlay.root, activeTheme);
|
|
2486
3246
|
applyLocalEditorTheme(shortcutHelpPanel, activeTheme);
|
|
2487
3247
|
applyLocalEditorTheme(assetPreviewModal, activeTheme);
|
|
2488
3248
|
applyLocalEditorTheme(assetPickerModal, activeTheme);
|
|
@@ -3002,6 +3762,9 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3002
3762
|
performanceMonitorButton.addEventListener('click', () => {
|
|
3003
3763
|
setPerformanceMonitorOpen(!performanceMonitorOpen);
|
|
3004
3764
|
});
|
|
3765
|
+
prefabComparisonPreviewButton.addEventListener('click', () => {
|
|
3766
|
+
setPrefabComparisonPreviewOpen(!prefabComparisonPreviewOpen);
|
|
3767
|
+
});
|
|
3005
3768
|
gridToggleButton.addEventListener('click', () => {
|
|
3006
3769
|
const visible = currentState?.grid?.visible ?? true;
|
|
3007
3770
|
callbacks.onGridVisibleChange?.(!visible);
|
|
@@ -3055,6 +3818,12 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3055
3818
|
callbacks.onViewportProjectionModeChange?.(nextMode);
|
|
3056
3819
|
return;
|
|
3057
3820
|
}
|
|
3821
|
+
const markerVisibilityToggle = target?.closest('[data-viewport-marker-visibility-toggle]');
|
|
3822
|
+
if (markerVisibilityToggle) {
|
|
3823
|
+
const markersVisible = currentState?.viewportTools?.markersVisible ?? true;
|
|
3824
|
+
callbacks.onMarkerViewportVisibilityChange?.(!markersVisible);
|
|
3825
|
+
return;
|
|
3826
|
+
}
|
|
3058
3827
|
const overlayToggle = target?.closest('[data-viewport-overlay-settings-toggle]');
|
|
3059
3828
|
if (overlayToggle) {
|
|
3060
3829
|
event.stopPropagation();
|
|
@@ -3088,10 +3857,21 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3088
3857
|
contextMenu.close();
|
|
3089
3858
|
performanceMonitorOpen = open;
|
|
3090
3859
|
LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
|
|
3091
|
-
renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' ? currentState.performanceStats ?? null : null, currentState?.mode === 'editor' && performanceMonitorOpen);
|
|
3860
|
+
renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' && !currentState.prefabStage ? currentState.performanceStats ?? null : null, currentState?.mode === 'editor' && !currentState.prefabStage && performanceMonitorOpen);
|
|
3092
3861
|
if (notify)
|
|
3093
3862
|
callbacks.onPerformanceMonitorOpenChange?.(performanceMonitorOpen);
|
|
3094
3863
|
};
|
|
3864
|
+
const setPrefabComparisonPreviewOpen = (open) => {
|
|
3865
|
+
if (prefabComparisonPreviewOpen === open)
|
|
3866
|
+
return;
|
|
3867
|
+
if (!open)
|
|
3868
|
+
endPrefabComparisonPreviewDrag();
|
|
3869
|
+
prefabComparisonPreviewOpen = open;
|
|
3870
|
+
if (currentState)
|
|
3871
|
+
renderPreviewState(currentState);
|
|
3872
|
+
LocalEditorShared.applyButtonActiveState(prefabComparisonPreviewButton, prefabComparisonPreviewOpen);
|
|
3873
|
+
callbacks.onPrefabComparisonPreviewLayoutChange?.();
|
|
3874
|
+
};
|
|
3095
3875
|
const openAssetPreviewModal = (asset) => {
|
|
3096
3876
|
if (!asset.preview)
|
|
3097
3877
|
return;
|
|
@@ -3164,7 +3944,10 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3164
3944
|
}
|
|
3165
3945
|
function renderAssetPreviewModal() {
|
|
3166
3946
|
const asset = resolvePreviewedAssetFromState();
|
|
3167
|
-
if (!assetPreviewOpen
|
|
3947
|
+
if (!assetPreviewOpen
|
|
3948
|
+
|| !asset
|
|
3949
|
+
|| (assetPreviewMode === 'preview' && !asset.preview)
|
|
3950
|
+
|| (assetPreviewMode === 'material-editor' && !asset.material)) {
|
|
3168
3951
|
assetPreviewModal.style.display = 'none';
|
|
3169
3952
|
assetPreviewTitle.textContent = '';
|
|
3170
3953
|
assetPreviewMeta.textContent = '';
|
|
@@ -3404,7 +4187,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3404
4187
|
const options = [{ label: '继承 / 无', value: '', meta: '清空贴图引用' }];
|
|
3405
4188
|
const seen = new Set(['']);
|
|
3406
4189
|
for (const asset of currentState?.assets ?? []) {
|
|
3407
|
-
if (
|
|
4190
|
+
if (resolveLocalEditorBrowserAssetKind(asset) !== 'texture')
|
|
3408
4191
|
continue;
|
|
3409
4192
|
const value = asset.preview?.kind === 'image'
|
|
3410
4193
|
? asset.preview.url
|
|
@@ -3564,6 +4347,9 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3564
4347
|
sceneHelpButton.addEventListener('click', () => {
|
|
3565
4348
|
setShortcutHelpOpen(!helpOpen);
|
|
3566
4349
|
});
|
|
4350
|
+
prefabStageBackButton.addEventListener('click', () => {
|
|
4351
|
+
callbacks.onExitPrefabStage?.();
|
|
4352
|
+
});
|
|
3567
4353
|
themeToggleButton.addEventListener('click', () => {
|
|
3568
4354
|
setActiveTheme(activeTheme === 'dark' ? 'light' : 'dark');
|
|
3569
4355
|
});
|
|
@@ -3583,9 +4369,9 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3583
4369
|
closeAssetPreviewModal();
|
|
3584
4370
|
});
|
|
3585
4371
|
assetPreviewBody.addEventListener('change', (event) => {
|
|
4372
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
3586
4373
|
if (assetPreviewMode !== 'material-editor')
|
|
3587
4374
|
return;
|
|
3588
|
-
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
3589
4375
|
const input = target?.closest('[data-editor-asset-material-field]');
|
|
3590
4376
|
if (!input)
|
|
3591
4377
|
return;
|
|
@@ -3764,6 +4550,10 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3764
4550
|
openAssetMaterialEditorModal(asset);
|
|
3765
4551
|
return;
|
|
3766
4552
|
}
|
|
4553
|
+
if (item.id === 'asset.edit-prefab') {
|
|
4554
|
+
callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset));
|
|
4555
|
+
return;
|
|
4556
|
+
}
|
|
3767
4557
|
if (item.id === 'asset.copy-id') {
|
|
3768
4558
|
copyTextToClipboard(doc.defaultView, asset.assetId ?? asset.id);
|
|
3769
4559
|
return;
|
|
@@ -3776,7 +4566,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3776
4566
|
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
3777
4567
|
const openTabButton = target?.closest('[data-editor-open-right-dock-tab]');
|
|
3778
4568
|
const openTab = openTabButton?.dataset.editorOpenRightDockTab;
|
|
3779
|
-
if (openTab
|
|
4569
|
+
if (isLocalEditorRightDockTab(openTab)) {
|
|
3780
4570
|
panelRegistry.setRightDockTab(openTab);
|
|
3781
4571
|
if (currentState)
|
|
3782
4572
|
render(currentState);
|
|
@@ -3784,7 +4574,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3784
4574
|
}
|
|
3785
4575
|
const tabButton = target?.closest('[data-editor-right-dock-tab]');
|
|
3786
4576
|
const tab = tabButton?.dataset.editorRightDockTab;
|
|
3787
|
-
if (tab
|
|
4577
|
+
if (isLocalEditorRightDockTab(tab)) {
|
|
3788
4578
|
panelRegistry.setRightDockTab(tab);
|
|
3789
4579
|
if (currentState)
|
|
3790
4580
|
render(currentState);
|
|
@@ -3792,6 +4582,12 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3792
4582
|
});
|
|
3793
4583
|
workbench.leftDock.addEventListener('click', (event) => {
|
|
3794
4584
|
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
4585
|
+
const prefabStageItem = target?.closest('[data-editor-prefab-stage-item]');
|
|
4586
|
+
const prefabStageItemId = prefabStageItem?.dataset.editorPrefabStageItem;
|
|
4587
|
+
if (prefabStageItemId) {
|
|
4588
|
+
callbacks.onSelectPrefabStageItem?.(prefabStageItemId);
|
|
4589
|
+
return;
|
|
4590
|
+
}
|
|
3795
4591
|
const tabButton = target?.closest('[data-editor-left-dock-tab]');
|
|
3796
4592
|
const tab = tabButton?.dataset.editorLeftDockTab;
|
|
3797
4593
|
if (tab === 'hierarchy') {
|
|
@@ -3800,6 +4596,15 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3800
4596
|
render(currentState);
|
|
3801
4597
|
}
|
|
3802
4598
|
});
|
|
4599
|
+
workbench.leftDock.addEventListener('input', (event) => {
|
|
4600
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
4601
|
+
const input = target?.closest('[data-editor-prefab-stage-explorer-search]');
|
|
4602
|
+
if (!input)
|
|
4603
|
+
return;
|
|
4604
|
+
prefabStageExplorerFilter = input.value;
|
|
4605
|
+
if (currentState)
|
|
4606
|
+
render(currentState);
|
|
4607
|
+
});
|
|
3803
4608
|
const hierarchyController = createLocalEditorHierarchyController({
|
|
3804
4609
|
doc,
|
|
3805
4610
|
panel: hierarchyPanel,
|
|
@@ -3882,6 +4687,28 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
3882
4687
|
callbacks.onRenderingAction?.(actionInput);
|
|
3883
4688
|
return;
|
|
3884
4689
|
}
|
|
4690
|
+
const inspectorActionButton = target?.closest('[data-editor-inspector-action]');
|
|
4691
|
+
if (inspectorActionButton) {
|
|
4692
|
+
if (inspectorActionButton.disabled)
|
|
4693
|
+
return;
|
|
4694
|
+
const actionInput = createInspectorActionInput(inspectorActionButton);
|
|
4695
|
+
if (!actionInput)
|
|
4696
|
+
return;
|
|
4697
|
+
event.preventDefault();
|
|
4698
|
+
event.stopPropagation();
|
|
4699
|
+
callbacks.onInspectorAction?.(actionInput);
|
|
4700
|
+
return;
|
|
4701
|
+
}
|
|
4702
|
+
const relationTarget = target?.closest('[data-editor-marker-relation-action]');
|
|
4703
|
+
if (relationTarget && !(relationTarget instanceof HTMLButtonElement && relationTarget.disabled)) {
|
|
4704
|
+
const relationInput = createMarkerRelationActionInput(relationTarget);
|
|
4705
|
+
if (!relationInput)
|
|
4706
|
+
return;
|
|
4707
|
+
event.preventDefault();
|
|
4708
|
+
event.stopPropagation();
|
|
4709
|
+
callbacks.onMarkerRelationAction?.(relationInput);
|
|
4710
|
+
return;
|
|
4711
|
+
}
|
|
3885
4712
|
const vectorLockButton = target?.closest('[data-editor-inspector-vector-lock]');
|
|
3886
4713
|
if (vectorLockButton) {
|
|
3887
4714
|
const groupPath = vectorLockButton.dataset.editorInspectorVectorLock;
|
|
@@ -4084,6 +4911,28 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4084
4911
|
openStaticShadowBakePopover();
|
|
4085
4912
|
callbacks.onRenderingAction?.(actionInput);
|
|
4086
4913
|
});
|
|
4914
|
+
markersPanel.addEventListener('click', (event) => {
|
|
4915
|
+
const eventTarget = event.target instanceof HTMLElement ? event.target : null;
|
|
4916
|
+
const relationTarget = eventTarget?.closest('[data-editor-marker-relation-action]');
|
|
4917
|
+
if (relationTarget && !(relationTarget instanceof HTMLButtonElement && relationTarget.disabled)) {
|
|
4918
|
+
const relationInput = createMarkerRelationActionInput(relationTarget);
|
|
4919
|
+
if (!relationInput)
|
|
4920
|
+
return;
|
|
4921
|
+
event.preventDefault();
|
|
4922
|
+
event.stopPropagation();
|
|
4923
|
+
callbacks.onMarkerRelationAction?.(relationInput);
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
const actionButton = eventTarget?.closest('[data-editor-marker-type-action]');
|
|
4927
|
+
if (!actionButton || actionButton.disabled)
|
|
4928
|
+
return;
|
|
4929
|
+
const actionInput = createMarkerTypeActionInput(actionButton);
|
|
4930
|
+
if (!actionInput)
|
|
4931
|
+
return;
|
|
4932
|
+
event.preventDefault();
|
|
4933
|
+
event.stopPropagation();
|
|
4934
|
+
callbacks.onMarkerTypeAction?.(actionInput);
|
|
4935
|
+
});
|
|
4087
4936
|
const onKeyDown = (event) => {
|
|
4088
4937
|
if (event.defaultPrevented)
|
|
4089
4938
|
return;
|
|
@@ -4125,9 +4974,27 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4125
4974
|
closeStaticShadowBakePopover();
|
|
4126
4975
|
return;
|
|
4127
4976
|
}
|
|
4977
|
+
if (key === 'escape' && currentState?.prefabStage) {
|
|
4978
|
+
event.preventDefault();
|
|
4979
|
+
callbacks.onExitPrefabStage?.();
|
|
4980
|
+
return;
|
|
4981
|
+
}
|
|
4128
4982
|
const primaryModifier = event.metaKey || event.ctrlKey;
|
|
4129
4983
|
const handleDocumentShortcut = inputRouter.shouldHandleDocumentShortcut(event);
|
|
4130
4984
|
const handleGlobalShortcut = inputRouter.shouldHandleGlobalShortcut(event);
|
|
4985
|
+
if (shouldToggleLocalEditorPrefabComparisonShortcut({
|
|
4986
|
+
inPrefabStage: currentState.prefabStage != null,
|
|
4987
|
+
handleGlobalShortcut,
|
|
4988
|
+
key,
|
|
4989
|
+
shiftKey: event.shiftKey,
|
|
4990
|
+
metaKey: event.metaKey,
|
|
4991
|
+
ctrlKey: event.ctrlKey,
|
|
4992
|
+
altKey: event.altKey,
|
|
4993
|
+
})) {
|
|
4994
|
+
event.preventDefault();
|
|
4995
|
+
setPrefabComparisonPreviewOpen(!prefabComparisonPreviewOpen);
|
|
4996
|
+
return;
|
|
4997
|
+
}
|
|
4131
4998
|
if (handleDocumentShortcut && localTestActionsEnabled && primaryModifier && key === 's') {
|
|
4132
4999
|
event.preventDefault();
|
|
4133
5000
|
callbacks.onSaveScene?.();
|
|
@@ -4146,9 +5013,22 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4146
5013
|
callbacks.onRedo?.();
|
|
4147
5014
|
return;
|
|
4148
5015
|
}
|
|
4149
|
-
if (
|
|
5016
|
+
if (shouldLocalEditorPrefabStageBlockHierarchyShortcut({
|
|
5017
|
+
inPrefabStage: currentState.prefabStage != null,
|
|
5018
|
+
handleGlobalShortcut,
|
|
5019
|
+
key,
|
|
5020
|
+
metaKey: event.metaKey,
|
|
5021
|
+
ctrlKey: event.ctrlKey,
|
|
5022
|
+
altKey: event.altKey,
|
|
5023
|
+
})) {
|
|
5024
|
+
event.preventDefault();
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
if (!currentState.prefabStage && handleGlobalShortcut && hierarchyController.handleEditShortcut(event)) {
|
|
4150
5028
|
return;
|
|
4151
5029
|
}
|
|
5030
|
+
if (currentState.prefabStage)
|
|
5031
|
+
return;
|
|
4152
5032
|
if (!handleGlobalShortcut || event.metaKey || event.ctrlKey || event.altKey)
|
|
4153
5033
|
return;
|
|
4154
5034
|
const toolByKey = {
|
|
@@ -4190,8 +5070,276 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4190
5070
|
? operationState.canAlign
|
|
4191
5071
|
: operationState.canDistribute;
|
|
4192
5072
|
}
|
|
5073
|
+
function applyPrefabStageWorkbenchLayoutOverride(layout = workbenchLayoutController.getLayout()) {
|
|
5074
|
+
const leftWidth = Math.min(Math.max(layout.leftWidth, 220), 420);
|
|
5075
|
+
const rightWidth = Math.min(Math.max(layout.rightWidth, 300), 520);
|
|
5076
|
+
workbench.leftDock.style.display = 'flex';
|
|
5077
|
+
workbench.leftDock.style.width = `${leftWidth}px`;
|
|
5078
|
+
workbench.leftDock.style.bottom = '0';
|
|
5079
|
+
workbench.leftDock.style.zIndex = '';
|
|
5080
|
+
workbench.leftDock.style.boxShadow = '';
|
|
5081
|
+
workbench.rightDock.style.display = 'flex';
|
|
5082
|
+
workbench.rightDock.style.width = `${rightWidth}px`;
|
|
5083
|
+
workbench.rightDock.style.zIndex = '';
|
|
5084
|
+
workbench.rightDock.style.boxShadow = '';
|
|
5085
|
+
workbench.sceneFrame.style.left = `${leftWidth}px`;
|
|
5086
|
+
workbench.sceneFrame.style.right = `${rightWidth}px`;
|
|
5087
|
+
workbench.sceneFrame.style.bottom = '0';
|
|
5088
|
+
workbench.bottomDock.style.display = 'none';
|
|
5089
|
+
workbench.bottomResizer.style.display = 'none';
|
|
5090
|
+
workbench.bottomToggle.style.display = 'none';
|
|
5091
|
+
workbench.leftToggle.style.display = 'none';
|
|
5092
|
+
workbench.rightToggle.style.display = 'none';
|
|
5093
|
+
workbench.leftResizer.style.bottom = '0';
|
|
5094
|
+
workbench.rightResizer.style.bottom = '0';
|
|
5095
|
+
}
|
|
5096
|
+
function renderPrefabStageStructurePanel(stage) {
|
|
5097
|
+
LocalEditorShared.clearElement(hierarchyPanel);
|
|
5098
|
+
hierarchyPanel.dataset.editorPanelId = 'prefab-explorer';
|
|
5099
|
+
hierarchyPanel.appendChild(createPrefabStagePanelHeader('Prefab Explorer', 'hierarchy'));
|
|
5100
|
+
const search = doc.createElement('input');
|
|
5101
|
+
search.type = 'search';
|
|
5102
|
+
search.dataset.editorPrefabStageExplorerSearch = 'true';
|
|
5103
|
+
search.placeholder = 'Filter';
|
|
5104
|
+
search.value = prefabStageExplorerFilter;
|
|
5105
|
+
search.style.cssText = [
|
|
5106
|
+
'width:calc(100% - 16px)',
|
|
5107
|
+
'height:28px',
|
|
5108
|
+
'margin:6px 8px 8px',
|
|
5109
|
+
'padding:0 8px',
|
|
5110
|
+
'border:1px solid var(--fps-editor-border-strong)',
|
|
5111
|
+
'border-radius:0',
|
|
5112
|
+
'background:var(--fps-editor-input-bg)',
|
|
5113
|
+
'color:var(--fps-editor-text)',
|
|
5114
|
+
'font-size:12px',
|
|
5115
|
+
'font-weight:700',
|
|
5116
|
+
'outline:none',
|
|
5117
|
+
].join(';');
|
|
5118
|
+
hierarchyPanel.appendChild(search);
|
|
5119
|
+
if (stage.importStructureReady === false) {
|
|
5120
|
+
const loading = doc.createElement('div');
|
|
5121
|
+
loading.textContent = 'Loading import structure...';
|
|
5122
|
+
loading.style.cssText = 'padding:0 8px 8px;color:var(--fps-editor-muted);font-size:11px;font-weight:800';
|
|
5123
|
+
hierarchyPanel.appendChild(loading);
|
|
5124
|
+
}
|
|
5125
|
+
const list = doc.createElement('div');
|
|
5126
|
+
list.style.cssText = 'display:flex;flex-direction:column;gap:1px';
|
|
5127
|
+
const visibleItems = filterLocalEditorPrefabStageStructureItems(stage.structureItems, prefabStageExplorerFilter);
|
|
5128
|
+
const renderItem = (item, depth) => {
|
|
5129
|
+
const button = doc.createElement('button');
|
|
5130
|
+
button.type = 'button';
|
|
5131
|
+
button.dataset.editorPrefabStageItem = item.id;
|
|
5132
|
+
const selected = stage.selectedItemId === item.id;
|
|
5133
|
+
const icon = isLocalEditorIconName(item.icon)
|
|
5134
|
+
? item.icon
|
|
5135
|
+
: item.kind === 'root'
|
|
5136
|
+
? 'prefab'
|
|
5137
|
+
: item.kind === 'source'
|
|
5138
|
+
? 'asset'
|
|
5139
|
+
: item.kind === 'material'
|
|
5140
|
+
? 'material-slot'
|
|
5141
|
+
: item.kind === 'texture'
|
|
5142
|
+
? 'asset'
|
|
5143
|
+
: item.kind === 'animation'
|
|
5144
|
+
? 'execute'
|
|
5145
|
+
: item.kind === 'group'
|
|
5146
|
+
? 'group'
|
|
5147
|
+
: 'object';
|
|
5148
|
+
button.style.cssText = [
|
|
5149
|
+
'width:100%',
|
|
5150
|
+
'min-height:26px',
|
|
5151
|
+
'display:flex',
|
|
5152
|
+
'align-items:center',
|
|
5153
|
+
'gap:6px',
|
|
5154
|
+
`padding:3px 8px 3px ${8 + depth * 16}px`,
|
|
5155
|
+
`border:1px solid ${selected ? 'var(--fps-editor-accent)' : 'transparent'}`,
|
|
5156
|
+
'border-radius:0',
|
|
5157
|
+
`background:${selected ? 'var(--fps-editor-row-selected)' : 'transparent'}`,
|
|
5158
|
+
`color:${selected ? 'var(--fps-editor-row-selected-text)' : 'var(--fps-editor-text)'}`,
|
|
5159
|
+
'font-size:12px',
|
|
5160
|
+
'font-weight:800',
|
|
5161
|
+
'text-align:left',
|
|
5162
|
+
'cursor:pointer',
|
|
5163
|
+
'overflow:hidden',
|
|
5164
|
+
].join(';');
|
|
5165
|
+
button.appendChild(createLocalEditorIcon(doc, icon, { size: 14 }));
|
|
5166
|
+
const label = doc.createElement('span');
|
|
5167
|
+
label.textContent = item.label;
|
|
5168
|
+
label.style.cssText = 'min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1';
|
|
5169
|
+
button.appendChild(label);
|
|
5170
|
+
if (item.readonly === true) {
|
|
5171
|
+
const readonlyBadge = doc.createElement('span');
|
|
5172
|
+
readonlyBadge.textContent = 'READONLY';
|
|
5173
|
+
readonlyBadge.style.cssText = [
|
|
5174
|
+
'flex:0 0 auto',
|
|
5175
|
+
'padding:1px 4px',
|
|
5176
|
+
'border-radius:2px',
|
|
5177
|
+
'background:var(--fps-editor-chip-bg)',
|
|
5178
|
+
'color:var(--fps-editor-muted-strong)',
|
|
5179
|
+
'font-size:9px',
|
|
5180
|
+
'font-weight:900',
|
|
5181
|
+
].join(';');
|
|
5182
|
+
button.appendChild(readonlyBadge);
|
|
5183
|
+
}
|
|
5184
|
+
list.appendChild(button);
|
|
5185
|
+
for (const child of item.children ?? [])
|
|
5186
|
+
renderItem(child, depth + 1);
|
|
5187
|
+
};
|
|
5188
|
+
for (const item of visibleItems)
|
|
5189
|
+
renderItem(item, 0);
|
|
5190
|
+
if (visibleItems.length === 0) {
|
|
5191
|
+
const empty = doc.createElement('div');
|
|
5192
|
+
empty.textContent = prefabStageExplorerFilter.trim() ? 'No matching items.' : 'No structure available.';
|
|
5193
|
+
empty.style.cssText = 'padding:8px;color:var(--fps-editor-muted);font-size:12px;font-weight:800';
|
|
5194
|
+
list.appendChild(empty);
|
|
5195
|
+
}
|
|
5196
|
+
hierarchyPanel.appendChild(list);
|
|
5197
|
+
}
|
|
5198
|
+
function renderPrefabStagePropertiesPanel(stage) {
|
|
5199
|
+
inspectorPanel.dataset.editorPanelId = 'prefab-properties';
|
|
5200
|
+
inspectorPanel.style.display = '';
|
|
5201
|
+
renderingPanel.style.display = 'none';
|
|
5202
|
+
if (stage.inspectorObject) {
|
|
5203
|
+
LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, {
|
|
5204
|
+
...currentState,
|
|
5205
|
+
selectedIds: stage.inspectorObject.targetIds,
|
|
5206
|
+
activeId: stage.inspectorObject.activeId,
|
|
5207
|
+
selectionSummary: {
|
|
5208
|
+
count: stage.inspectorObject.targetIds.length,
|
|
5209
|
+
activeId: stage.inspectorObject.activeId,
|
|
5210
|
+
},
|
|
5211
|
+
serializedObject: null,
|
|
5212
|
+
serializedMultiObject: null,
|
|
5213
|
+
inspectorObject: stage.inspectorObject,
|
|
5214
|
+
inspectorMultiObject: null,
|
|
5215
|
+
}, inspectorFilter, {
|
|
5216
|
+
...options.inspector,
|
|
5217
|
+
title: 'Prefab Properties',
|
|
5218
|
+
emptyText: 'Select an item in Prefab Explorer.',
|
|
5219
|
+
summaryTitle: 'Prefab',
|
|
5220
|
+
lockedVectorGroups: lockedInspectorVectorGroups,
|
|
5221
|
+
});
|
|
5222
|
+
return;
|
|
5223
|
+
}
|
|
5224
|
+
LocalEditorShared.clearElement(inspectorPanel);
|
|
5225
|
+
inspectorPanel.appendChild(createPrefabStagePanelHeader('Prefab Properties', 'inspector'));
|
|
5226
|
+
const selectedItem = findLocalEditorPrefabStageStructureItem(stage, stage.selectedItemId);
|
|
5227
|
+
const grid = doc.createElement('div');
|
|
5228
|
+
grid.style.cssText = 'display:flex;flex-direction:column;gap:7px;min-width:0';
|
|
5229
|
+
appendPrefabStageReadonlyRow(grid, '名称', stage.label);
|
|
5230
|
+
appendPrefabStageReadonlyRow(grid, 'Prefab ID', stage.assetId);
|
|
5231
|
+
appendPrefabStageReadonlyRow(grid, 'Source', stage.sourceAssetId ?? '未设置');
|
|
5232
|
+
appendPrefabStageReadonlyRow(grid, 'Preview', stage.previewNodeId ?? '未生成');
|
|
5233
|
+
appendPrefabStageReadonlyRow(grid, 'Selected', selectedItem?.label ?? stage.selectedItemId ?? 'Prefab Root');
|
|
5234
|
+
appendPrefabStageReadonlyRow(grid, 'Mode', stage.readonly ? '只读' : '可编辑');
|
|
5235
|
+
appendPrefabStageSelectedItemDetails(grid, selectedItem);
|
|
5236
|
+
inspectorPanel.appendChild(grid);
|
|
5237
|
+
}
|
|
5238
|
+
function appendPrefabStageSelectedItemDetails(container, item) {
|
|
5239
|
+
if (!item)
|
|
5240
|
+
return;
|
|
5241
|
+
appendPrefabStageReadonlyRow(container, 'Kind', item.kind);
|
|
5242
|
+
if (item.sourceAssetId)
|
|
5243
|
+
appendPrefabStageReadonlyRow(container, 'Source Asset', item.sourceAssetId);
|
|
5244
|
+
if (item.slotId)
|
|
5245
|
+
appendPrefabStageReadonlyRow(container, 'Slot ID', item.slotId);
|
|
5246
|
+
if (item.ownerNodePath)
|
|
5247
|
+
appendPrefabStageReadonlyRow(container, 'Owner Path', item.ownerNodePath);
|
|
5248
|
+
if (item.meshIndex != null)
|
|
5249
|
+
appendPrefabStageReadonlyRow(container, 'Mesh Index', String(item.meshIndex));
|
|
5250
|
+
if (item.primitiveIndex != null)
|
|
5251
|
+
appendPrefabStageReadonlyRow(container, 'Primitive', String(item.primitiveIndex));
|
|
5252
|
+
if (item.sourceMaterialIndex != null) {
|
|
5253
|
+
appendPrefabStageReadonlyRow(container, 'Material Index', String(item.sourceMaterialIndex));
|
|
5254
|
+
}
|
|
5255
|
+
if (item.sourceMaterialIndices?.length) {
|
|
5256
|
+
appendPrefabStageReadonlyRow(container, 'Material Indices', item.sourceMaterialIndices.join(', '));
|
|
5257
|
+
}
|
|
5258
|
+
if (item.sourceMaterialName)
|
|
5259
|
+
appendPrefabStageReadonlyRow(container, 'Material Name', item.sourceMaterialName);
|
|
5260
|
+
if (item.sourceMaterialNames?.length) {
|
|
5261
|
+
appendPrefabStageReadonlyRow(container, 'Material Names', item.sourceMaterialNames.join(', '));
|
|
5262
|
+
}
|
|
5263
|
+
if (item.meta)
|
|
5264
|
+
appendPrefabStageReadonlyRow(container, 'Meta', item.meta);
|
|
5265
|
+
}
|
|
5266
|
+
function resolvePrefabStageAssetFromState(stage) {
|
|
5267
|
+
return currentState?.assets.find(asset => (asset.id === stage.browserAssetId
|
|
5268
|
+
|| asset.id === `prefab:${stage.assetId}`
|
|
5269
|
+
|| asset.assetId === stage.assetId
|
|
5270
|
+
|| asset.prefab?.id === stage.assetId)) ?? null;
|
|
5271
|
+
}
|
|
5272
|
+
function createPrefabStagePanelHeader(title, icon) {
|
|
5273
|
+
const header = doc.createElement('div');
|
|
5274
|
+
header.style.cssText = [
|
|
5275
|
+
'display:flex',
|
|
5276
|
+
'align-items:center',
|
|
5277
|
+
'gap:8px',
|
|
5278
|
+
'min-height:30px',
|
|
5279
|
+
'margin:-8px -8px 8px',
|
|
5280
|
+
'padding:0 8px',
|
|
5281
|
+
'border-bottom:1px solid var(--fps-editor-divider)',
|
|
5282
|
+
'background:var(--fps-editor-chrome-dark)',
|
|
5283
|
+
].join(';');
|
|
5284
|
+
header.appendChild(createLocalEditorIcon(doc, icon, { size: 14 }));
|
|
5285
|
+
const label = doc.createElement('h2');
|
|
5286
|
+
label.textContent = title;
|
|
5287
|
+
label.style.cssText = [
|
|
5288
|
+
'min-width:0',
|
|
5289
|
+
'margin:0',
|
|
5290
|
+
'overflow:hidden',
|
|
5291
|
+
'text-overflow:ellipsis',
|
|
5292
|
+
'white-space:nowrap',
|
|
5293
|
+
'font-size:13px',
|
|
5294
|
+
'font-weight:800',
|
|
5295
|
+
'color:var(--fps-editor-text-strong)',
|
|
5296
|
+
].join(';');
|
|
5297
|
+
header.appendChild(label);
|
|
5298
|
+
return header;
|
|
5299
|
+
}
|
|
5300
|
+
function appendPrefabStageReadonlyRow(container, label, value) {
|
|
5301
|
+
const row = doc.createElement('div');
|
|
5302
|
+
row.style.cssText = [
|
|
5303
|
+
'display:grid',
|
|
5304
|
+
'grid-template-columns:92px minmax(0,1fr)',
|
|
5305
|
+
'gap:8px',
|
|
5306
|
+
'align-items:center',
|
|
5307
|
+
'min-height:26px',
|
|
5308
|
+
].join(';');
|
|
5309
|
+
const rowLabel = doc.createElement('div');
|
|
5310
|
+
rowLabel.textContent = label;
|
|
5311
|
+
rowLabel.style.cssText = [
|
|
5312
|
+
'min-width:0',
|
|
5313
|
+
'overflow:hidden',
|
|
5314
|
+
'text-overflow:ellipsis',
|
|
5315
|
+
'white-space:nowrap',
|
|
5316
|
+
'color:var(--fps-editor-muted)',
|
|
5317
|
+
'font-size:11px',
|
|
5318
|
+
'font-weight:800',
|
|
5319
|
+
].join(';');
|
|
5320
|
+
const output = doc.createElement('div');
|
|
5321
|
+
output.textContent = value;
|
|
5322
|
+
output.title = value;
|
|
5323
|
+
output.style.cssText = [
|
|
5324
|
+
'min-width:0',
|
|
5325
|
+
'overflow:hidden',
|
|
5326
|
+
'text-overflow:ellipsis',
|
|
5327
|
+
'white-space:nowrap',
|
|
5328
|
+
'padding:4px 7px',
|
|
5329
|
+
'border:1px solid var(--fps-editor-border)',
|
|
5330
|
+
'border-radius:3px',
|
|
5331
|
+
'background:var(--fps-editor-field)',
|
|
5332
|
+
'color:var(--fps-editor-text-strong)',
|
|
5333
|
+
'font-size:12px',
|
|
5334
|
+
'font-weight:800',
|
|
5335
|
+
].join(';');
|
|
5336
|
+
row.appendChild(rowLabel);
|
|
5337
|
+
row.appendChild(output);
|
|
5338
|
+
container.appendChild(row);
|
|
5339
|
+
}
|
|
4193
5340
|
const renderPreviewState = (state) => {
|
|
4194
5341
|
const inEditor = state.mode === 'editor';
|
|
5342
|
+
const inPrefabStage = !!state.prefabStage;
|
|
4195
5343
|
const disabled = state.busy;
|
|
4196
5344
|
const transformTool = state.transformTool ?? null;
|
|
4197
5345
|
const transformOperations = state.transformOperations ?? {
|
|
@@ -4235,8 +5383,22 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4235
5383
|
? 'var(--fps-editor-border)'
|
|
4236
5384
|
: statusToneColor;
|
|
4237
5385
|
renderCoordinateAxesOverlay(coordinateAxesOverlay, inEditor ? state.coordinateAxes ?? null : null);
|
|
4238
|
-
renderSceneFrameRateOverlay(sceneFrameRateOverlay, inEditor ? state.sceneFrameStats ?? null : null);
|
|
4239
|
-
renderPerformanceMonitorOverlay(performanceMonitorOverlay, inEditor ? state.performanceStats ?? null : null, inEditor && performanceMonitorOpen);
|
|
5386
|
+
renderSceneFrameRateOverlay(sceneFrameRateOverlay, inEditor && !inPrefabStage ? state.sceneFrameStats ?? null : null);
|
|
5387
|
+
renderPerformanceMonitorOverlay(performanceMonitorOverlay, inEditor && !inPrefabStage ? state.performanceStats ?? null : null, inEditor && !inPrefabStage && performanceMonitorOpen);
|
|
5388
|
+
const comparisonColumnVisible = shouldShowLocalEditorPrefabComparisonColumn({
|
|
5389
|
+
inPrefabStage: inEditor && inPrefabStage,
|
|
5390
|
+
userOpen: prefabComparisonPreviewOpen,
|
|
5391
|
+
sceneWidth: workbench.sceneFrame.clientWidth,
|
|
5392
|
+
});
|
|
5393
|
+
if (!comparisonColumnVisible)
|
|
5394
|
+
endPrefabComparisonPreviewDrag();
|
|
5395
|
+
prefabStagePreviewLayout.root.style.display = inEditor && inPrefabStage ? 'block' : 'none';
|
|
5396
|
+
prefabStagePreviewLayout.mainRegion.style.right = comparisonColumnVisible
|
|
5397
|
+
? `${LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX}px`
|
|
5398
|
+
: '0';
|
|
5399
|
+
prefabStagePreviewLayout.comparisonColumn.style.display = comparisonColumnVisible ? 'flex' : 'none';
|
|
5400
|
+
renderPrefabImportStatsOverlay(prefabImportStatsOverlay, inEditor && inPrefabStage ? state.prefabStage ?? null : null);
|
|
5401
|
+
renderPrefabComparisonPreviewOverlay(prefabComparisonPreviewOverlay, inEditor && inPrefabStage && comparisonColumnVisible ? state.prefabStage ?? null : null);
|
|
4240
5402
|
renderSpatialOverlay(spatialOverlay, inEditor ? state.viewportSpatialOverlay ?? null : null);
|
|
4241
5403
|
renderMeasurementOverlay(measurementOverlay, inEditor ? state.viewportMeasurement ?? null : null);
|
|
4242
5404
|
const boxSelection = state.boxSelection;
|
|
@@ -4263,38 +5425,44 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4263
5425
|
};
|
|
4264
5426
|
renderPreviewState(currentState);
|
|
4265
5427
|
if (shouldRenderInspectorPreview && panelRegistry.getRightDockTab() === 'inspector') {
|
|
4266
|
-
const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel);
|
|
5428
|
+
const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel);
|
|
4267
5429
|
LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, currentState, inspectorFilter, {
|
|
4268
5430
|
...options.inspector,
|
|
4269
5431
|
lockedVectorGroups: lockedInspectorVectorGroups,
|
|
4270
5432
|
});
|
|
4271
|
-
restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel);
|
|
5433
|
+
restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel);
|
|
4272
5434
|
}
|
|
4273
5435
|
};
|
|
4274
5436
|
const render = (state) => {
|
|
4275
5437
|
const previousState = currentState;
|
|
4276
5438
|
const previousRightTab = panelRegistry.getRightDockTab();
|
|
4277
|
-
const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(previousState, previousRightTab, inspectorFilter, inspectorPanel, renderingPanel);
|
|
5439
|
+
const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(previousState, previousRightTab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel);
|
|
4278
5440
|
currentState = state;
|
|
4279
5441
|
const focusSnapshot = captureLocalEditorEditableFocus(doc);
|
|
4280
5442
|
const inEditor = state.mode === 'editor';
|
|
4281
5443
|
const disabled = state.busy;
|
|
5444
|
+
const prefabStage = inEditor ? state.prefabStage ?? null : null;
|
|
5445
|
+
const inPrefabStage = !!prefabStage;
|
|
5446
|
+
if (!inPrefabStage || previousState?.prefabStage?.assetId !== prefabStage.assetId) {
|
|
5447
|
+
prefabStageExplorerFilter = '';
|
|
5448
|
+
}
|
|
4282
5449
|
if (!inEditor || disabled)
|
|
4283
5450
|
contextMenu.close();
|
|
4284
5451
|
hostChrome.style.display = !inEditor && localTestActionsEnabled ? 'flex' : 'none';
|
|
4285
5452
|
enterEditorButton.disabled = disabled;
|
|
4286
|
-
for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, performanceMonitorButton, gridToggleButton]) {
|
|
5453
|
+
for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, performanceMonitorButton, gridToggleButton, prefabComparisonPreviewButton]) {
|
|
4287
5454
|
button.style.display = 'inline-flex';
|
|
4288
5455
|
button.disabled = disabled;
|
|
4289
5456
|
}
|
|
4290
|
-
localTestGroup.style.display = inEditor && localTestActionsEnabled ? 'flex' : 'none';
|
|
5457
|
+
localTestGroup.style.display = inEditor && !inPrefabStage && localTestActionsEnabled ? 'flex' : 'none';
|
|
4291
5458
|
localTestButton.disabled = disabled;
|
|
4292
5459
|
if (!inEditor || !localTestActionsEnabled)
|
|
4293
5460
|
closeLocalTestMenu();
|
|
4294
5461
|
if (!inEditor)
|
|
4295
5462
|
helpOpen = false;
|
|
4296
|
-
if (
|
|
5463
|
+
if (shouldLocalEditorClosePerformanceMonitor({ inEditor, inPrefabStage, performanceMonitorOpen })) {
|
|
4297
5464
|
setPerformanceMonitorOpen(false);
|
|
5465
|
+
}
|
|
4298
5466
|
if (!inEditor || disabled) {
|
|
4299
5467
|
assetPreviewOpen = false;
|
|
4300
5468
|
previewedAsset = null;
|
|
@@ -4306,7 +5474,16 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4306
5474
|
syncInputModalOpen();
|
|
4307
5475
|
const transformTool = state.transformTool ?? null;
|
|
4308
5476
|
workbench.root.style.display = inEditor ? '' : 'none';
|
|
5477
|
+
workbench.root.dataset.editorPrefabStage = String(inPrefabStage);
|
|
5478
|
+
sceneTitle.textContent = createLocalEditorPrefabStageTitle(prefabStage);
|
|
4309
5479
|
sceneToolOverlay.style.display = inEditor ? 'flex' : 'none';
|
|
5480
|
+
prefabStageBackButton.style.display = inPrefabStage ? 'inline-flex' : 'none';
|
|
5481
|
+
workbench.leftToggle.style.display = '';
|
|
5482
|
+
workbench.rightToggle.style.display = '';
|
|
5483
|
+
workbench.bottomToggle.style.display = '';
|
|
5484
|
+
workbenchLayoutController.refresh();
|
|
5485
|
+
if (inPrefabStage)
|
|
5486
|
+
applyPrefabStageWorkbenchLayoutOverride();
|
|
4310
5487
|
if (!inEditor)
|
|
4311
5488
|
closeSnapSettingsPopover();
|
|
4312
5489
|
if (!inEditor)
|
|
@@ -4318,7 +5495,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4318
5495
|
if (!inEditor)
|
|
4319
5496
|
closeStaticShadowBakePopover();
|
|
4320
5497
|
const staticShadowBakeAction = findLocalEditorRenderingAction(state.renderingPanel, STATIC_SHADOW_BAKE_ACTION_ID);
|
|
4321
|
-
const staticShadowBakeVisible = inEditor && !!staticShadowBakeAction;
|
|
5498
|
+
const staticShadowBakeVisible = inEditor && !inPrefabStage && !!staticShadowBakeAction;
|
|
4322
5499
|
staticShadowBakeGroup.style.display = staticShadowBakeVisible ? 'flex' : 'none';
|
|
4323
5500
|
const staticShadowBakeDisabled = disabled || !staticShadowBakeAction || staticShadowBakeAction.action.disabled === true;
|
|
4324
5501
|
staticShadowBakeButton.disabled = staticShadowBakeDisabled;
|
|
@@ -4330,7 +5507,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4330
5507
|
LocalEditorShared.applyButtonActiveState(staticShadowBakeButton, !!staticShadowBakeAction?.system?.progress);
|
|
4331
5508
|
renderStaticShadowBakePopover(state);
|
|
4332
5509
|
const sceneCameraPreview = state.sceneCameraPreview ?? { enabled: false, available: false };
|
|
4333
|
-
cameraPreviewGroup.style.display = inEditor ? 'flex' : 'none';
|
|
5510
|
+
cameraPreviewGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
4334
5511
|
sceneCameraButton.disabled = disabled || !sceneCameraPreview.available;
|
|
4335
5512
|
const sceneCameraTooltip = sceneCameraPreview.available
|
|
4336
5513
|
? '从 Main Camera 查看当前场景'
|
|
@@ -4357,6 +5534,10 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4357
5534
|
setToolbarButtonIcon(doc, projectionToggleButton, projectionMode === 'orthographic' ? 'projection-ortho' : 'projection-perspective');
|
|
4358
5535
|
setToolbarButtonTooltip(projectionToggleButton, viewportProjectionTooltip || `投影模式:${VIEWPORT_PROJECTION_LABELS[projectionMode]}。切换为${VIEWPORT_PROJECTION_LABELS[nextProjectionMode]}`);
|
|
4359
5536
|
LocalEditorShared.applyButtonActiveState(projectionToggleButton, projectionMode === 'orthographic');
|
|
5537
|
+
const markersVisible = viewportTools?.markersVisible ?? true;
|
|
5538
|
+
markerVisibilityButton.disabled = disabled;
|
|
5539
|
+
setToolbarButtonTooltip(markerVisibilityButton, markersVisible ? '隐藏标记与关系线' : '显示标记与关系线');
|
|
5540
|
+
LocalEditorShared.applyButtonActiveState(markerVisibilityButton, markersVisible);
|
|
4360
5541
|
overlaySettingsButton.disabled = disabled;
|
|
4361
5542
|
setToolbarButtonTooltip(overlaySettingsButton, '视口信息层设置');
|
|
4362
5543
|
LocalEditorShared.applyButtonActiveState(overlaySettingsButton, overlaySettingsOpen);
|
|
@@ -4378,12 +5559,21 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4378
5559
|
if (!inEditor || disabled || viewportToolsGroup.style.display === 'none')
|
|
4379
5560
|
closeOverlaySettingsPopover();
|
|
4380
5561
|
const gridState = state.grid ?? { visible: false, available: false };
|
|
4381
|
-
performanceMonitorButton.
|
|
5562
|
+
performanceMonitorButton.style.display = inPrefabStage ? 'none' : 'inline-flex';
|
|
5563
|
+
performanceMonitorButton.disabled = disabled || inPrefabStage;
|
|
4382
5564
|
setToolbarButtonTooltip(performanceMonitorButton, performanceMonitorOpen ? '隐藏性能监控' : '显示性能监控');
|
|
4383
5565
|
LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
|
|
5566
|
+
prefabComparisonPreviewButton.style.display = inPrefabStage ? 'inline-flex' : 'none';
|
|
5567
|
+
prefabComparisonPreviewButton.disabled = disabled || !inPrefabStage;
|
|
5568
|
+
setToolbarButtonTooltip(prefabComparisonPreviewButton, prefabComparisonPreviewOpen
|
|
5569
|
+
? '隐藏对比预览 (Shift+P)'
|
|
5570
|
+
: '显示对比预览 (Shift+P)');
|
|
5571
|
+
LocalEditorShared.applyButtonActiveState(prefabComparisonPreviewButton, inPrefabStage && prefabComparisonPreviewOpen);
|
|
4384
5572
|
gridToggleButton.disabled = disabled || !gridState.available;
|
|
4385
5573
|
setToolbarButtonTooltip(gridToggleButton, gridState.visible ? '隐藏 Scene View 网格' : '显示 Scene View 网格');
|
|
4386
5574
|
LocalEditorShared.applyButtonActiveState(gridToggleButton, gridState.visible);
|
|
5575
|
+
toolGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
5576
|
+
spaceGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
4387
5577
|
for (const [tool, button] of toolButtons) {
|
|
4388
5578
|
button.disabled = disabled;
|
|
4389
5579
|
LocalEditorShared.applyButtonActiveState(button, transformTool?.activeTool === tool);
|
|
@@ -4401,7 +5591,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4401
5591
|
canDistribute: false,
|
|
4402
5592
|
};
|
|
4403
5593
|
const operationSettings = transformOperations.settings;
|
|
4404
|
-
snapGroup.style.display = inEditor ? 'flex' : 'none';
|
|
5594
|
+
snapGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
4405
5595
|
snapButton.disabled = disabled;
|
|
4406
5596
|
snapEnabledInput.disabled = disabled;
|
|
4407
5597
|
snapEnabledInput.checked = operationSettings.snap.enabled;
|
|
@@ -4414,7 +5604,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4414
5604
|
}
|
|
4415
5605
|
if (!inEditor || disabled || snapGroup.style.display === 'none')
|
|
4416
5606
|
closeSnapSettingsPopover();
|
|
4417
|
-
placementGroup.style.display = inEditor ? 'flex' : 'none';
|
|
5607
|
+
placementGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
4418
5608
|
placementButton.disabled = disabled;
|
|
4419
5609
|
setToolbarButtonIcon(doc, placementButton, PLACEMENT_MODE_ICONS[operationSettings.placementMode]);
|
|
4420
5610
|
setToolbarButtonTooltip(placementButton, `放置模式 · ${PLACEMENT_MODE_DESCRIPTIONS[operationSettings.placementMode]}`);
|
|
@@ -4425,7 +5615,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4425
5615
|
}
|
|
4426
5616
|
if (!inEditor || disabled || placementGroup.style.display === 'none')
|
|
4427
5617
|
closePlacementSettingsPopover();
|
|
4428
|
-
actionGroup.style.display = inEditor ? 'flex' : 'none';
|
|
5618
|
+
actionGroup.style.display = inEditor && !inPrefabStage ? 'flex' : 'none';
|
|
4429
5619
|
const hasTransformAction = transformOperations.canAlign || transformOperations.canDistribute;
|
|
4430
5620
|
transformActionButton.disabled = disabled || !hasTransformAction;
|
|
4431
5621
|
setToolbarButtonTooltip(transformActionButton, hasTransformAction ? '对齐与分布' : '选择至少 2 个对象后可用');
|
|
@@ -4449,9 +5639,29 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4449
5639
|
scheduleToolbarOverflowLayout();
|
|
4450
5640
|
if (!inEditor)
|
|
4451
5641
|
return;
|
|
5642
|
+
const activeRightTab = panelRegistry.getRightDockTab();
|
|
5643
|
+
if (inPrefabStage && prefabStage) {
|
|
5644
|
+
const rightDockVisibility = resolveLocalEditorRightDockVisibility({
|
|
5645
|
+
inPrefabStage: true,
|
|
5646
|
+
activeRightTab,
|
|
5647
|
+
});
|
|
5648
|
+
leftDockTabs.style.display = 'none';
|
|
5649
|
+
rightDockTabs.style.display = rightDockVisibility.tabsDisplay;
|
|
5650
|
+
inspectorPanel.style.display = rightDockVisibility.inspectorDisplay;
|
|
5651
|
+
renderingPanel.style.display = rightDockVisibility.renderingDisplay;
|
|
5652
|
+
renderPrefabStageStructurePanel(prefabStage);
|
|
5653
|
+
renderPrefabStagePropertiesPanel(prefabStage);
|
|
5654
|
+
restoreLocalEditorEditableFocus(doc, focusSnapshot);
|
|
5655
|
+
return;
|
|
5656
|
+
}
|
|
5657
|
+
leftDockTabs.style.display = '';
|
|
4452
5658
|
const hierarchyDescriptor = panelRegistry.getActivePanel('left');
|
|
4453
5659
|
const rightDescriptor = panelRegistry.getActivePanel('right');
|
|
4454
|
-
const
|
|
5660
|
+
const rightDockVisibility = resolveLocalEditorRightDockVisibility({
|
|
5661
|
+
inPrefabStage: false,
|
|
5662
|
+
activeRightTab,
|
|
5663
|
+
});
|
|
5664
|
+
rightDockTabs.style.display = rightDockVisibility.tabsDisplay;
|
|
4455
5665
|
const activeBottomTab = panelRegistry.getBottomDockTab();
|
|
4456
5666
|
const assetBrowserTabChanged = assetBrowserTab !== lastRenderedAssetBrowserTab;
|
|
4457
5667
|
const bottomDockTabChanged = activeBottomTab !== lastRenderedBottomDockTab;
|
|
@@ -4462,8 +5672,10 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4462
5672
|
hierarchyPanel.dataset.editorPanelId = hierarchyDescriptor?.id ?? 'hierarchy';
|
|
4463
5673
|
inspectorPanel.dataset.editorPanelId = activeRightTab === 'inspector' ? rightDescriptor?.id ?? 'inspector' : 'inspector';
|
|
4464
5674
|
renderingPanel.dataset.editorPanelId = activeRightTab === 'rendering' ? rightDescriptor?.id ?? 'rendering' : 'rendering';
|
|
4465
|
-
|
|
4466
|
-
|
|
5675
|
+
markersPanel.dataset.editorPanelId = activeRightTab === 'markers' ? rightDescriptor?.id ?? 'markers' : 'markers';
|
|
5676
|
+
inspectorPanel.style.display = rightDockVisibility.inspectorDisplay;
|
|
5677
|
+
renderingPanel.style.display = rightDockVisibility.renderingDisplay;
|
|
5678
|
+
markersPanel.style.display = activeRightTab === 'markers' ? '' : 'none';
|
|
4467
5679
|
LocalEditorPanels.renderWorkbenchLeftDockTabs(doc, leftDockTabs, 'hierarchy', panelRegistry.getPanels('left'));
|
|
4468
5680
|
hierarchyController.render(state);
|
|
4469
5681
|
LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab);
|
|
@@ -4486,11 +5698,14 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4486
5698
|
lockedVectorGroups: lockedInspectorVectorGroups,
|
|
4487
5699
|
});
|
|
4488
5700
|
}
|
|
4489
|
-
else {
|
|
5701
|
+
else if (activeRightTab === 'rendering') {
|
|
4490
5702
|
LocalEditorPanels.renderRenderingPanel(doc, renderingPanel, state);
|
|
4491
5703
|
}
|
|
5704
|
+
else {
|
|
5705
|
+
LocalEditorPanels.renderMarkerPanel(doc, markersPanel, state);
|
|
5706
|
+
}
|
|
4492
5707
|
restoreLocalEditorEditableFocus(doc, focusSnapshot);
|
|
4493
|
-
restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, state, activeRightTab, inspectorFilter, inspectorPanel, renderingPanel);
|
|
5708
|
+
restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, state, activeRightTab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel);
|
|
4494
5709
|
};
|
|
4495
5710
|
return {
|
|
4496
5711
|
update(state) {
|
|
@@ -4500,12 +5715,15 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4500
5715
|
updateSceneFrameStats(stats) {
|
|
4501
5716
|
if (currentState)
|
|
4502
5717
|
currentState = { ...currentState, sceneFrameStats: stats };
|
|
4503
|
-
renderSceneFrameRateOverlay(sceneFrameRateOverlay, currentState?.mode === 'editor' ? stats : null);
|
|
5718
|
+
renderSceneFrameRateOverlay(sceneFrameRateOverlay, currentState?.mode === 'editor' && !currentState.prefabStage ? stats : null);
|
|
4504
5719
|
},
|
|
4505
5720
|
updatePerformanceStats(stats) {
|
|
4506
5721
|
if (currentState)
|
|
4507
5722
|
currentState = { ...currentState, performanceStats: stats };
|
|
4508
|
-
renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' ? stats : null, currentState?.mode === 'editor' && performanceMonitorOpen);
|
|
5723
|
+
renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' && !currentState.prefabStage ? stats : null, currentState?.mode === 'editor' && !currentState.prefabStage && performanceMonitorOpen);
|
|
5724
|
+
},
|
|
5725
|
+
getPrefabComparisonPreviewSurfaces() {
|
|
5726
|
+
return readPrefabComparisonPreviewSurfaces(prefabComparisonPreviewOverlay);
|
|
4509
5727
|
},
|
|
4510
5728
|
setTheme(theme) {
|
|
4511
5729
|
setActiveTheme(theme);
|
|
@@ -4535,6 +5753,7 @@ export function createLocalEditorBrowserUi(options = {}) {
|
|
|
4535
5753
|
measurementOverlay.root.remove();
|
|
4536
5754
|
sceneFrameRateOverlay.root.remove();
|
|
4537
5755
|
performanceMonitorOverlay.root.remove();
|
|
5756
|
+
prefabStagePreviewLayout.root.remove();
|
|
4538
5757
|
boxSelectionOverlay.remove();
|
|
4539
5758
|
shortcutHelpPanel.remove();
|
|
4540
5759
|
assetPreviewModal.remove();
|