diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/BuildSceneViewportToolCommand.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/BuildSceneViewportToolCommand.md new file mode 100644 index 00000000..0ea27837 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/BuildSceneViewportToolCommand.md @@ -0,0 +1,43 @@ +# BuildSceneViewportToolCommand + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 签名 + +```cpp +SceneViewportToolCommand BuildSceneViewportToolCommand( + const SceneViewportToolOverlayResult& overlayResult, + const SceneViewportToolShortcutAction& shortcutAction); +``` + +## 作用 + +把工具按钮点击和键盘快捷键动作折叠成统一的 Scene View 工具命令。 + +## 当前实现行为 + +- 如果 `overlayResult.clicked == true`: + - 先把 `targetTool` 设为 `overlayResult.clickedTool` + - 置 `triggered = true` + - 并默认要求取消 move / rotate / scale 三类 gizmo 拖拽 +- 如果 `shortcutAction.HasAction() == true`: + - 用快捷键目标覆盖 `targetTool` + - 保持 `triggered = true` + - 把三个 `cancel*Gizmo` 标志按逻辑或合并,而不是覆盖 + +`tests/Editor/test_scene_viewport_chrome.cpp` 当前验证了: + +- overlay 点击可以独立形成完整工具切换命令 +- 快捷键可以在 overlay 未触发时生成命令 +- 当两者同时触发时,快捷键会覆盖目标工具,但保留 cancel 标志并集 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md) +- [SceneViewportToolCommand](SceneViewportToolCommand.md) +- [SceneViewportToolShortcutAction](../SceneViewportNavigation/SceneViewportToolShortcutAction.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/ExecuteSceneViewportToolCommand.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/ExecuteSceneViewportToolCommand.md new file mode 100644 index 00000000..bf749aaa --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/ExecuteSceneViewportToolCommand.md @@ -0,0 +1,43 @@ +# ExecuteSceneViewportToolCommand + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 签名 + +```cpp +void ExecuteSceneViewportToolCommand( + const SceneViewportToolCommand& command, + IUndoManager& undoManager, + SceneViewportMoveGizmo& moveGizmo, + SceneViewportRotateGizmo& rotateGizmo, + SceneViewportScaleGizmo& scaleGizmo, + SceneViewportToolMode& toolMode); +``` + +## 作用 + +执行工具切换命令,并在切换前按需安全结束当前 gizmo 交互拖拽。 + +## 当前实现行为 + +1. 如果 `command.HasAction() == false`,直接 `no-op` +2. 根据 `cancelMoveGizmo / cancelRotateGizmo / cancelScaleGizmo`: + - 只在对应 gizmo 当前 `IsActive()` 时才调用 `CancelDrag(&undoManager)` +3. 最后把 `toolMode` 改成 `command.targetTool` + +这意味着它既负责“切工具”,也负责在切工具前安全收口当前交互式拖拽。 + +## 当前边界 + +- 不生成命令,只执行命令。 +- 不直接刷新 gizmo frame,也不提交 overlay state。 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [SceneViewportToolCommand](SceneViewportToolCommand.md) +- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportToolOverlay.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportToolOverlay.md new file mode 100644 index 00000000..754b0258 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportToolOverlay.md @@ -0,0 +1,46 @@ +# RenderSceneViewportToolOverlay + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 签名 + +```cpp +SceneViewportToolOverlayResult RenderSceneViewportToolOverlay( + const ViewportPanelContentResult& content, + SceneViewportToolMode activeTool); +``` + +## 作用 + +在 Scene View 内容区左上角绘制工具按钮 overlay,并返回即时 UI 结果。 + +## 当前实现行为 + +- 当 `content.hasViewportArea == false` 时,直接返回空结果。 +- 当前固定绘制 5 个工具按钮: + - `ViewMove` + - `Move` + - `Rotate` + - `Scale` + - `Transform` +- 图标路径当前按 `resources/Icons/[_on].png` 规则拼接,并带静态缓存。 +- 如果图标预览加载失败,会退回文本绘制。 +- 只返回 `hovered / clicked / clickedTool`,不直接修改 `toolMode`。 + +## 返回值 + +返回 [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md): + +- `hovered` 表示鼠标是否位于任一工具按钮上 +- `clicked` 表示当前帧是否点击了某个工具按钮 +- `clickedTool` 表示点击命中的目标工具 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md) +- [SceneViewportToolMode](../SceneViewportEditorModes/SceneViewportToolMode.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportTopBar.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportTopBar.md new file mode 100644 index 00000000..96a2b4e3 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/RenderSceneViewportTopBar.md @@ -0,0 +1,39 @@ +# RenderSceneViewportTopBar + +**命名空间**: `XCEngine::Editor` + +**类型**: `function` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 签名 + +```cpp +void RenderSceneViewportTopBar( + SceneViewportPivotMode& pivotMode, + SceneViewportTransformSpaceMode& transformSpaceMode); +``` + +## 作用 + +绘制 Scene View 顶部 toolbar,并直接切换 `Pivot / Center` 与 `Global / Local` 两组模式。 + +## 当前实现行为 + +- 使用 `UI::PanelToolbarScope` 打开名为 `SceneToolbar` 的 toolbar 区域。 +- 如果 toolbar 没有打开,函数直接返回。 +- 当前只绘制两枚 toggle button: + - `Pivot` / `Center` + - `Global` / `Local` +- 每次点击都会在对应的两种模式之间直接翻转,不经过额外命令层。 + +## 当前边界 + +- 只改写 `pivotMode` 和 `transformSpaceMode`,不处理 `toolMode`。 +- 不负责命中解析、gizmo 刷新或导航状态。 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [SceneViewportPivotMode](../SceneViewportEditorModes/SceneViewportPivotMode.md) +- [SceneViewportTransformSpaceMode](../SceneViewportEditorModes/SceneViewportTransformSpaceMode.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportChrome.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportChrome.md index 5132b064..c4c7710a 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportChrome.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportChrome.md @@ -8,128 +8,60 @@ **描述**: 收口 Scene View 顶部 toolbar、左侧工具按钮 overlay,以及工具切换命令折叠与执行逻辑的 Viewport UI helper。 -## 概览 +## 概述 `SceneViewportChrome` 解决的是 `SceneViewPanel` 里最靠近 UI chrome 的那一层问题: -- 顶部 toolbar 如何切换 `Pivot / Center` 与 `Global / Local` -- 左侧工具按钮 overlay 如何反馈 hovered / clicked +- 顶部 toolbar 如何切换 `Pivot / Center` 和 `Global / Local` +- 左侧工具按钮 overlay 如何返回 hovered / clicked - 工具按钮点击与键盘快捷键如何折叠成统一命令 - 切换工具前哪些 gizmo 需要先取消交互式拖拽 -它本身不处理命中解析、导航输入、overlay frame 或 gizmo 生命周期命令;这些职责分别留在 -[SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)、 -[SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 和 -[SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。 +它本身不处理命中解析、导航输入、overlay frame 或 gizmo 生命周期命令;这些职责分别留在 [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)、[SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 和 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。 ## 公开类型与函数 -### `SceneViewportToolOverlayResult` +| 成员 | 说明 | +|------|------| +| [SceneViewportToolOverlayResult](SceneViewportToolOverlayResult.md) | 左侧工具按钮 overlay 的即时 UI 结果。 | +| [SceneViewportToolCommand](SceneViewportToolCommand.md) | 把点击与快捷键折叠后的统一工具命令。 | +| [RenderSceneViewportTopBar](RenderSceneViewportTopBar.md) | 绘制并切换顶部 `Pivot / Center` 与 `Global / Local` toolbar。 | +| [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md) | 绘制视口左上角工具按钮 overlay。 | +| [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) | 把 overlay 点击与快捷键动作折叠成统一工具命令。 | +| [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) | 真正执行工具切换,并按需取消现有 gizmo 拖拽。 | -记录左侧工具按钮 overlay 的即时 UI 结果: +## 调用链 -- `hovered` - - 鼠标当前是否落在任意工具按钮上 -- `clicked` - - 本帧是否发生按钮点击 -- `clickedTool` - - 若发生点击,对应被选中的目标工具 +按 `editor/src/panels/SceneViewPanel.cpp` 的当前实现,Scene View 每帧会按下面顺序消费这份 header: -`SceneViewPanel` 当前用它把“鼠标是否停在工具按钮上”从视口内容 hovered 状态里扣掉,避免点击工具按钮时误走 Scene View 内容交互。 - -### `SceneViewportToolCommand` - -把工具按钮点击与键盘快捷键统一成一份可执行命令: - -- `targetTool` -- `triggered` -- `cancelMoveGizmo` -- `cancelRotateGizmo` -- `cancelScaleGizmo` - -`HasAction()` 当前只是返回 `triggered`,不附带额外 guard。 - -### `RenderSceneViewportTopBar(...)` - -绘制顶部 toolbar,并直接更新: - -- `SceneViewportPivotMode` -- `SceneViewportTransformSpaceMode` - -当前实现使用两枚 toggle button: - -- `Pivot` / `Center` -- `Global` / `Local` - -每次点击都会在两种模式之间直接翻转,不经过额外命令层。 - -### `RenderSceneViewportToolOverlay(...)` - -在视口内容左上角绘制 5 个工具按钮: - -- `ViewMove` -- `Move` -- `Rotate` -- `Scale` -- `Transform` - -当前实现行为是: - -- `content.hasViewportArea == false` 时直接返回空结果 -- 优先按当前可执行文件目录推导 `resources/Icons/[_on].png` -- 如果图标贴图预览失败,则退回文字 tooltip / 文本绘制 -- 只返回即时 UI 结果,不直接修改 `toolMode` - -### `BuildSceneViewportToolCommand(...)` - -把两路输入折叠成统一工具命令: - -- 鼠标点击 overlay 按钮 -- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 产出的快捷键动作 - -当前规则是: - -- overlay 点击一旦命中,默认会要求取消全部 gizmo 拖拽 -- 若快捷键动作也触发,会覆盖 `targetTool` -- 三个 `cancel*` 标志按逻辑或合并,而不是互相覆盖 - -### `ExecuteSceneViewportToolCommand(...)` - -真正执行工具切换命令。 - -当前实现会: - -1. 若 `HasAction() == false`,直接 no-op -2. 对 `move / rotate / scale` gizmo 分别按 `cancel*` 标志决定是否调用 `CancelDrag(&undoManager)` -3. 最后把 `toolMode` 改成 `targetTool` - -这意味着它既负责“切工具”,也负责在切工具前安全结束当前交互式拖拽。 - -## 当前调用链 - -按 `SceneViewPanel.cpp` 的当前实现,Scene View 每帧会按下面的顺序消费这份 header: - -1. 先调用 `RenderSceneViewportTopBar(...)` -2. 再调用 `RenderSceneViewportToolOverlay(...)` -3. 用 `BuildSceneViewportToolShortcutAction(...)` 生成快捷键动作 -4. 再用 `BuildSceneViewportToolCommand(...)` 合并 UI 点击和快捷键 -5. 最后用 `ExecuteSceneViewportToolCommand(...)` 更新 `m_toolMode` +1. 先调用 [RenderSceneViewportTopBar](RenderSceneViewportTopBar.md) +2. 再调用 [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md) +3. 用 [BuildSceneViewportToolShortcutAction](../SceneViewportNavigation/BuildSceneViewportToolShortcutAction.md) 生成快捷键动作 +4. 再用 [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) 合并 UI 点击和快捷键 +5. 最后用 [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) 更新 `m_toolMode` 也就是说,这一层是 `SceneViewPanel` 进入 `tool state / interaction frame / navigation state` 之前的最前置 UI chrome 装配层。 +## 测试锚点 + +`tests/Editor/test_scene_viewport_chrome.cpp` 当前覆盖了: + +- overlay 点击触发的完整工具切换命令 +- 快捷键动作在 overlay 未触发时的工具命令映射 +- 快捷键覆盖 overlay 目标工具、但保留 cancel 标志并集 +- 执行工具命令时对 `toolMode` 的更新 + ## 当前边界 -- 它只服务于 Scene View UI chrome,不参与 Game View。 -- 它不负责判断“当前是否允许解析 Scene View 内容交互”;这部分在 [CanResolveSceneViewportInteraction](../SceneViewportNavigation/SceneViewportNavigation.md)。 -- 它不直接刷新 gizmo frame,也不提交 overlay state;这部分在 [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md) 与 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。 -- 当前已有独立单元测试 `tests/Editor/test_scene_viewport_chrome.cpp`,覆盖工具命令折叠与执行规则。 -- 顶部 toolbar / 左侧按钮 overlay 的绘制细节仍主要由 `editor/src/Viewport/SceneViewportChrome.cpp` 与 `editor/src/panels/SceneViewPanel.cpp` 共同锚定。 +- 只服务于 Scene View UI chrome,不参与 Game View。 +- 绘制细节主要锚定在 `editor/src/Viewport/SceneViewportChrome.cpp`;`SceneViewPanel.cpp` 当前只负责按帧编排调用。 +- `RenderSceneViewportToolOverlay(...)` 只返回即时 UI 结果,不直接改写 `toolMode`。 ## 相关文档 - [Viewport](../Viewport.md) - [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) - [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md) -- [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md) - [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) +- [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md) - [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolCommand.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolCommand.md new file mode 100644 index 00000000..2100da1a --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolCommand.md @@ -0,0 +1,28 @@ +# SceneViewportToolCommand + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `targetTool` | `SceneViewportToolMode` | 最终要切换到的工具。默认值是 `Move`。 | +| `triggered` | `bool` | 当前帧是否真的形成工具切换命令。 | +| `cancelMoveGizmo` | `bool` | 执行前是否需要取消 move gizmo 拖拽。 | +| `cancelRotateGizmo` | `bool` | 执行前是否需要取消 rotate gizmo 拖拽。 | +| `cancelScaleGizmo` | `bool` | 执行前是否需要取消 scale gizmo 拖拽。 | + +## 当前语义 + +- `HasAction()` 当前只返回 `triggered`。 +- 这是轻量命令对象,真正的取消拖拽与工具切换由 [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) 完成。 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) +- [ExecuteSceneViewportToolCommand](ExecuteSceneViewportToolCommand.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolOverlayResult.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolOverlayResult.md new file mode 100644 index 00000000..44769935 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportChrome/SceneViewportToolOverlayResult.md @@ -0,0 +1,26 @@ +# SceneViewportToolOverlayResult + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportChrome.h` + +## 字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `hovered` | `bool` | 鼠标当前是否落在任意工具按钮上。 | +| `clicked` | `bool` | 本帧是否发生工具按钮点击。 | +| `clickedTool` | `SceneViewportToolMode` | 若发生点击,对应被选中的目标工具。默认值是 `Move`。 | + +## 当前语义 + +- `SceneViewPanel::Render()` 当前会把 `toolOverlay.hovered` 从 viewport 内容悬停判定里扣掉,避免点工具按钮时误走 Scene View 内容交互。 +- `clickedTool` 只在 `clicked == true` 时有实际语义。 + +## 相关文档 + +- [SceneViewportChrome](SceneViewportChrome.md) +- [RenderSceneViewportToolOverlay](RenderSceneViewportToolOverlay.md) +- [BuildSceneViewportToolCommand](BuildSceneViewportToolCommand.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md index cd61206e..fa5fe317 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/ApplySceneViewportRenderPlan.md @@ -17,7 +17,7 @@ void ApplySceneViewportRenderPlan( ## 作用 -把已经构建好的 `SceneViewportRenderPlan` 写入目标 `CameraRenderRequest`。 +把已经构建好的 [SceneViewportRenderPlan](SceneViewportRenderPlan.md) 写入目标 `CameraRenderRequest`,使本帧 Scene View request 具备 editor 专属附加行为。 ## 当前实现行为 @@ -35,19 +35,56 @@ ApplySceneViewportRenderRequestSetup( 1. 如果 `plan.HasOverlayPasses()` 为真,把 `request.overlayPasses` 指向 `plan.overlayPasses` 2. 无条件把 `plan.hasClearColorOverride` 和 `plan.clearColorOverride` 复制到 request +## 与 `ApplySceneViewportRenderRequestSetup(...)` 的分工 + +[ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md) 负责的是 Scene View request 的基础接线: + +- 清理旧的 `preScenePasses` / `postScenePasses` / `overlayPasses` +- 清理旧的 object-id 设置 +- 按条件接入 `postScenePasses` +- 按条件接入 object-id surface + +而本函数只在这之后补两件 Scene View render plan 语义: + +- overlay pass +- clear-color override + +因此这两个函数不是重复关系,而是“基础 request 装配”与“render plan 应用”的上下层关系。 + ## 当前语义边界 -- object-id surface 和 `postScenePasses` 的挂接规则,仍由 `ApplySceneViewportRenderRequestSetup(...)` 定义。 -- 该函数不负责生成 `request.surface`,也不负责构建 plan,只负责“把 plan 应用到 request”。 -- `overlayPasses` 只有在非空时才会挂到 request;空序列不会暴露出去。 +- 它不负责构建 `request.surface`。 +- 它不负责决定本帧 plan 里应该有哪些 pass。 +- 它不会强行把空的 overlay 序列挂到 request 上。 +- 它会始终把 clear-color override 从 plan 写回 request,即使本帧没有额外 pass。 + +最后一点非常关键,因为 Scene View 默认背景色本来就是 plan 语义的一部分,而不依赖当前有没有 grid / overlay。 ## 测试锚点 -- `ApplySceneViewportRenderPlanAttachesPlannedPassesAndClearState` +`ApplySceneViewportRenderPlanAttachesPlannedPassesAndClearState` 验证了: + +- `request.postScenePasses` 会指向 `plan.postScenePasses` +- `request.overlayPasses` 会在非空时接入 +- object-id surface 会被请求 +- clear-color override 会被正确写回 + +## 设计说明 + +把“把 plan 应用到 request”单独收口,是为了保证 `ViewportHostService` 最核心的 Scene View 执行路径足够稳定: + +1. 先拿到运行时 `CameraRenderRequest` +2. 再在 Editor 层补 plan +3. 最后统一交给 `SceneRenderer` + +这比在 service 里零散地改 request 各字段更可靠,因为所有 Scene View 附加语义都通过同一个入口回写,减少了遗漏和跨帧残留指针的风险。 ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) -- [HasOverlayPasses](HasOverlayPasses.md) - [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) +- [HasOverlayPasses](HasOverlayPasses.md) +- [ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md) - [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md) +- [CameraRenderRequest](../../../Rendering/CameraRenderRequest/CameraRenderRequest.md) +- [Scene View Render Plan And Failure Flow](../../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasOverlayPasses.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasOverlayPasses.md index ba6a09c5..0637efad 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasOverlayPasses.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasOverlayPasses.md @@ -18,7 +18,7 @@ bool HasOverlayPasses() const; ## 当前实现行为 -当前只是返回: +当前实现只是返回: ```cpp overlayPasses.GetPassCount() > 0 @@ -26,8 +26,28 @@ overlayPasses.GetPassCount() > 0 这也是 [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md) 决定是否把 `request.overlayPasses` 指向 `plan.overlayPasses` 的直接依据。 +## 当前语义 + +这里的 overlay pass 当前主要指 editor overlay: + +- 相机与灯光辅助图标 +- transform gizmo 图元 +- 其他由 `SceneViewportOverlayFrameData` 驱动的屏幕叠加几何 + +## 设计说明 + +overlay pass 是 Scene View 比运行时视图更“编辑器化”的一层。 + +把它和 post-scene pass 分开判断,可以让调用方更明确地区分: + +- 这是场景空间增强 +- 还是最终叠加层 + +这对后续继续扩展 Scene View pass 类型会很重要。 + ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) - [HasPostScenePasses](HasPostScenePasses.md) - [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md) +- [SceneViewportOverlayPassFactory](SceneViewportOverlayPassFactory.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasPostScenePasses.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasPostScenePasses.md index 62ed095b..c6469c3a 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasPostScenePasses.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/HasPostScenePasses.md @@ -18,7 +18,7 @@ bool HasPostScenePasses() const; ## 当前实现行为 -当前只是返回: +当前实现只是返回: ```cpp postScenePasses.GetPassCount() > 0 @@ -26,8 +26,22 @@ postScenePasses.GetPassCount() > 0 因此空的 `RenderPassSequence` 不会被视为“已配置 post-scene pass”。 +## 当前语义 + +这里的 post-scene pass 当前主要包括: + +- Scene View 无限网格 +- selection outline + +它们都属于“在主场景之后追加,但仍然围绕场景空间语义工作”的 pass。 + +## 设计说明 + +把这个判断留在 plan 上,而不是散落到各个调用点,有助于维持 API 语义统一:调用方不需要自己看 pass count,只需要问“这个 plan 有没有 post-scene pass”。 + ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) - [HasOverlayPasses](HasOverlayPasses.md) +- [ApplySceneViewportRenderRequestSetup](../ViewportHostRenderFlowUtils/ApplySceneViewportRenderRequestSetup.md) - [ApplySceneViewportRenderPlan](ApplySceneViewportRenderPlan.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportGridPassFactory.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportGridPassFactory.md index 5b1bc7dd..299dc663 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportGridPassFactory.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportGridPassFactory.md @@ -19,11 +19,25 @@ using SceneViewportGridPassFactory = ## 当前语义 -- 输入是一份已经由 `BuildSceneViewportGridPassData(...)` 组装好的 `InfiniteGridPassData`。 -- 输出是要追加到 `SceneViewportRenderPlan::postScenePasses` 的一个 `RenderPass`。 -- 返回 `nullptr` 时,本帧不会追加网格 pass。 +- 输入是一份已由 [BuildSceneViewportGridPassData](../ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md) 组装好的 `InfiniteGridPassData` +- 输出是要追加到 `SceneViewportRenderPlan::postScenePasses` 的 `RenderPass` +- 返回 `nullptr` 时,本帧不会追加 grid pass + +## 真实使用位置 + +`ViewportHostService::BuildSceneViewportRenderState(...)` 会把它绑定到: + +- `CreateSceneViewportGridPass(m_sceneViewportGridRenderer, data)` + +而 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 只负责决定是否调用它,并在返回非空时把 pass 收进 plan。 + +## 设计说明 + +把“何时需要 grid”与“如何创建 grid pass”拆开,是当前 render plan 设计里很重要的一条原则。这样做能让规划层只关心条件判断,而把 renderer 生命周期和 GPU 细节留给 service。 ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) - [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) +- [BuildSceneViewportGridPassData](../ViewportHostRenderFlowUtils/BuildSceneViewportGridPassData.md) +- [SceneViewportGridPass](../Passes/SceneViewportGridPass/SceneViewportGridPass.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportOverlayPassFactory.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportOverlayPassFactory.md index 2fe52bb9..c6044e62 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportOverlayPassFactory.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportOverlayPassFactory.md @@ -15,17 +15,36 @@ using SceneViewportOverlayPassFactory = ## 作用 -描述一个“由合成后的 overlay frame data 生成 GPU overlay pass”的工厂回调。 +描述一个“根据合成后的 `SceneViewportOverlayFrameData` 生成 editor overlay pass”的工厂回调。 ## 当前语义 -- 输入是已经合并好的 `SceneViewportOverlayFrameData` -- 输出是要追加到 `SceneViewportRenderPlan::overlayPasses` 的一个 `RenderPass` +- 输入是已经由 `SceneViewportOverlayBuilder` 与 gizmo overlay state 合并后的 `SceneViewportOverlayFrameData` +- 输出是要追加到 `SceneViewportRenderPlan::overlayPasses` 的 `RenderPass` - 返回 `nullptr` 时,当前帧不会追加 overlay pass -这让 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 自己不依赖具体 pass 类型,只负责决定“何时创建 overlay pass、何时跳过”。 +## 真实使用位置 + +`ViewportHostService::BuildSceneViewportRenderState(...)` 当前把它绑定到: + +- `CreateSceneViewportEditorOverlayPass(...)` + +而 [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) 只负责在 `editorOverlayFrameData.HasOverlayPrimitives()` 为真时调用它。 + +## 设计说明 + +editor overlay 的重要点不是“它是一个 pass”,而是“它消费的是一份 canonical overlay frame data”。 + +把工厂参数直接设计成 `SceneViewportOverlayFrameData`,意味着: + +- hit-test 与最终渲染围绕同一份数据语义展开 +- plan 层不需要理解每种 primitive 的 GPU 细节 +- `ViewportHostService` 可以自由替换 overlay renderer 的具体实现 ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) - [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) +- [SceneViewportEditorOverlayData](../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) +- [SceneViewportEditorOverlayPass](../Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md) +- [Scene View Render Plan And Failure Flow](../../../../_guides/Editor/Scene-Viewport-Render-Plan-And-Failure-Flow.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlanBuildResult.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlanBuildResult.md index 98573639..bd4fa852 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlanBuildResult.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportRenderPlanBuildResult.md @@ -15,20 +15,42 @@ struct SceneViewportRenderPlanBuildResult { }; ``` -## 字段 +## 作用 + +同时返回: + +- 本帧构建出的 [SceneViewportRenderPlan](SceneViewportRenderPlan.md) +- 可选 warning 文案 + +这说明 `BuildSceneViewportRenderPlan(...)` 的结果不是单纯的“成功 / 失败”,而是“规划结果 + 可选降级提示”。 + +## 字段语义 | 字段 | 类型 | 说明 | |------|------|------| -| `plan` | `SceneViewportRenderPlan` | 当前帧构建出的渲染计划。 | -| `warningStatusText` | `const char*` | 可选警告文案,用于提示可降级但不必直接终止 Scene View 渲染的缺口。 | +| `plan` | `SceneViewportRenderPlan` | 当前帧构建出的 render plan;即便有 warning,也仍可能是可执行计划。 | +| `warningStatusText` | `const char*` | 可选 warning 文案,用于提示缺少某项 editor 能力,但不一定要终止 Scene View 渲染。 | ## 当前实现语义 -- 即使存在 `warningStatusText`,`plan` 也仍可能是可执行的有效计划。 -- 当前最典型的警告来源,是 Scene View 有选中对象、需要 selection outline,但 `objectIdShaderView` 不可用时返回的 `Scene object id shader view is unavailable`。 +- `warningStatusText == nullptr` 表示当前没有额外 warning。 +- 当前最典型的 warning 来源,是 Scene View 有选中对象、需要 selection outline,但 `objectIdShaderView` 不可用时返回的 `Scene object id shader view is unavailable`。 +- `ViewportHostService::BuildSceneViewportRenderState(...)` 会在拿到该结果后,通过 `SetViewportStatusIfEmpty(...)` 尝试保留 warning,而不是把它当成硬失败立即终止。 + +## 设计说明 + +编辑器渲染里最重要的一条经验是:**能力降级不等于整条链失败**。 + +例如 selection outline 没法画,并不代表 Scene View 主画面、网格或 gizmo 也应该一起消失。把 warning 从 plan 里显式带出来,能让上层: + +- 继续正常渲染 +- 同时仍然把缺口通知给用户 + +这比单纯返回布尔值更适合编辑器。 ## 相关文档 - [SceneViewportRenderPlan](SceneViewportRenderPlan.md) - [BuildSceneViewportRenderPlan](BuildSceneViewportRenderPlan.md) -- [ViewportHostRenderFlowUtils](../ViewportHostRenderFlowUtils/ViewportHostRenderFlowUtils.md) +- [SetViewportStatusIfEmpty](../ViewportHostRenderFlowUtils/SetViewportStatusIfEmpty.md) +- [ViewportHostService](../ViewportHostService/ViewportHostService.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportSelectionOutlinePassFactory.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportSelectionOutlinePassFactory.md index 8fe97435..1346d6b8 100644 --- a/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportSelectionOutlinePassFactory.md +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRenderPlan/SceneViewportSelectionOutlinePassFactory.md @@ -17,15 +17,42 @@ using SceneViewportSelectionOutlinePassFactory = std::function