docs: add scene viewport interaction and chrome docs

This commit is contained in:
2026-04-04 16:40:00 +08:00
parent 24245decb5
commit ee8b5e8c44
46 changed files with 1649 additions and 88 deletions

View File

@@ -0,0 +1,135 @@
# SceneViewportChrome
**命名空间**: `XCEngine::Editor`
**类型**: `utility header`
**源文件**: `editor/src/Viewport/SceneViewportChrome.h`
**描述**: 收口 Scene View 顶部 toolbar、左侧工具按钮 overlay以及工具切换命令折叠与执行逻辑的 Viewport UI helper。
## 概览
`SceneViewportChrome` 解决的是 `SceneViewPanel` 里最靠近 UI chrome 的那一层问题:
- 顶部 toolbar 如何切换 `Pivot / Center``Global / Local`
- 左侧工具按钮 overlay 如何反馈 hovered / clicked
- 工具按钮点击与键盘快捷键如何折叠成统一命令
- 切换工具前哪些 gizmo 需要先取消交互式拖拽
它本身不处理命中解析、导航输入、overlay frame 或 gizmo 生命周期命令;这些职责分别留在
[SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)、
[SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 和
[SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)。
## 公开类型与函数
### `SceneViewportToolOverlayResult`
记录左侧工具按钮 overlay 的即时 UI 结果:
- `hovered`
- 鼠标当前是否落在任意工具按钮上
- `clicked`
- 本帧是否发生按钮点击
- `clickedTool`
- 若发生点击,对应被选中的目标工具
`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/<tool>[_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`
也就是说,这一层是 `SceneViewPanel` 进入 `tool state / interaction frame / navigation state` 之前的最前置 UI chrome 装配层。
## 当前边界
- 它只服务于 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` 共同锚定。
## 相关文档
- [Viewport](../Viewport.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)
- [SceneViewportInteractionFrame](../SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md)
- [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)

View File

@@ -0,0 +1,41 @@
# SceneViewportEditorModes
**命名空间**: `XCEngine::Editor`
**类型**: `enum classes`
**源文件**: `editor/src/Viewport/SceneViewportEditorModes.h`
**描述**: 定义 Scene View 共享的工具模式、pivot 模式与变换空间模式。这些枚举从 `SceneViewPanel` 中拆出,供面板状态、交互帧组装和导航 helper 共同使用。
## 概述
`SceneViewportEditorModes.h` 不负责执行 gizmo 或导航逻辑,它只提供上层协调所需的模式枚举。
当前主要消费方包括:
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
持有当前工具、pivot 和空间模式。
- `SceneViewportInteractionFrame.h`
通过这些模式构造 `SceneViewportToolState` 与 gizmo frame options。
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md)
根据当前工具模式决定是否允许左键进入 view-move 导航。
## 公开类型
| 成员 | 说明 |
|------|------|
| [SceneViewportToolMode](SceneViewportToolMode.md) | Scene View 当前工具模式。 |
| [SceneViewportPivotMode](SceneViewportPivotMode.md) | `Pivot / Center` 枢轴模式。 |
| [SceneViewportTransformSpaceMode](SceneViewportTransformSpaceMode.md) | `Global / Local` 变换空间模式。 |
## 当前边界
- 这些枚举本身不持有 UI 标签、快捷键或图标资源。
- 具体模式如何影响 gizmo context要以下游 helper 的当前实现为准,而不是仅靠枚举名字推断。
## 相关文档
- [Viewport](../Viewport.md)
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)

View File

@@ -0,0 +1,25 @@
# SceneViewportPivotMode
**命名空间**: `XCEngine::Editor`
**类型**: `enum class`
**源文件**: `editor/src/Viewport/SceneViewportEditorModes.h`
## 枚举值
| 值 | 含义 |
|------|------|
| `Pivot` | 使用 primary selection 的 pivot 语义。 |
| `Center` | 请求使用 selection center 语义。当前 gizmo frame builder 会基于选中对象中心点聚合 pivot。 |
## 当前语义
- `SceneViewPanel` 默认把成员 `m_pivotMode` 初始化为 `Pivot`
- `SceneViewportInteractionFrame` 当前把 `Center` 翻译为 `useCenterPivot = true`,再交给 gizmo frame builder 处理。
- `tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了 `Center` 会把 `SceneViewportToolState::useCenterPivot` 置为 `true`
## 相关文档
- [SceneViewportEditorModes](SceneViewportEditorModes.md)
- [SceneView Interaction And Gizmo Model](../../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md)

View File

@@ -0,0 +1,30 @@
# SceneViewportToolMode
**命名空间**: `XCEngine::Editor`
**类型**: `enum class`
**源文件**: `editor/src/Viewport/SceneViewportEditorModes.h`
## 枚举值
| 值 | 含义 |
|------|------|
| `ViewMove` | 视图移动工具。当前 `SceneViewportNavigation` 会允许左键进入 pan drag且交互解析阶段会禁用 gizmo hit-test。 |
| `Move` | 仅显示 move gizmo。 |
| `Rotate` | 仅显示 rotate gizmo。 |
| `Scale` | 仅显示 scale gizmo。 |
| `Transform` | 组合工具。当前 `SceneViewportInteractionFrame` 会同时显示 move / rotate / scale gizmo并把 scale gizmo 置于 `uniformOnly` 语义。 |
## 当前语义
- `SceneViewPanel` 默认把成员 `m_toolMode` 初始化为 `Move`
- `tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了:
- `Move` 会打开 move gizmo关闭 rotate / scale gizmo。
- `Transform` 会同时打开三类 gizmo并把 `usingTransformTool` 置为 `true`
## 相关文档
- [SceneViewportEditorModes](SceneViewportEditorModes.md)
- [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)

View File

@@ -0,0 +1,25 @@
# SceneViewportTransformSpaceMode
**命名空间**: `XCEngine::Editor`
**类型**: `enum class`
**源文件**: `editor/src/Viewport/SceneViewportEditorModes.h`
## 枚举值
| 值 | 含义 |
|------|------|
| `Global` | 使用世界空间轴向。 |
| `Local` | 使用当前 primary selection 的稳定世界旋转作为 gizmo 轴向。 |
## 当前语义
- `SceneViewPanel` 默认把成员 `m_transformSpaceMode` 初始化为 `Global`
- `SceneViewportInteractionFrame` 当前把 `Local` 翻译为 `localSpace = true`,再交给各 gizmo context builder。
- `tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了 `Local` 会同步进入 `SceneViewportToolState::localSpace``gizmoFrameOptions.localSpace`
## 相关文档
- [SceneViewportEditorModes](SceneViewportEditorModes.md)
- [SceneView Interaction And Gizmo Model](../../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md)

View File

@@ -0,0 +1,31 @@
# BuildSceneViewportFrameGeometry
根据 viewport 矩形和绝对鼠标位置构建当前帧几何输入。
```cpp
SceneViewportFrameGeometry BuildSceneViewportFrameGeometry(
const ImVec2& viewportSize,
const ImVec2& viewportMin,
const ImVec2& absoluteMousePosition);
```
## 参数
- `viewportSize` - 当前 viewport 的可用尺寸。
- `viewportMin` - 当前 viewport 左上角的绝对屏幕坐标。
- `absoluteMousePosition` - 当前鼠标的绝对屏幕坐标。
## 当前语义
- `viewportSize` 会直接转成 `Math::Vector2`
- `localMousePosition` 通过 `absoluteMousePosition - viewportMin` 计算。
- 这里不做裁剪或悬停判断;即使鼠标已经跑出 viewport 外,本地坐标也会照常计算。
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了本地鼠标坐标的偏移计算。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportFrameGeometry](SceneViewportFrameGeometry.md)
- [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md)

View File

@@ -0,0 +1,52 @@
# BuildSceneViewportInteractionFrameState
组装当前 Scene View 单帧交互状态。
```cpp
SceneViewportInteractionFrameState BuildSceneViewportInteractionFrameState(
IEditorContext& context,
IViewportHostService& viewportHostService,
bool hasInteractiveViewport,
const SceneViewportFrameGeometry& geometry,
const SceneViewportTransformGizmoFrameOptions& gizmoFrameOptions,
SceneViewportMoveGizmo& moveGizmo,
SceneViewportRotateGizmo& rotateGizmo,
SceneViewportScaleGizmo& scaleGizmo,
const SceneViewportOverlayFrameData& emptyOverlayFrameData);
```
## 参数
- `context` - 当前 editor 上下文。
- `viewportHostService` - 当前 Scene View overlay 和 gizmo 数据来源。
- `hasInteractiveViewport` - 当前是否真的有可交互 viewport。
- `geometry` - 当前帧视口尺寸和本地鼠标几何。
- `gizmoFrameOptions` - 当前 gizmo frame 刷新配置。
- `moveGizmo` / `rotateGizmo` / `scaleGizmo` - 三类 gizmo 实例。
- `emptyOverlayFrameData` - 非交互 viewport 时使用的空 overlay frame。
## 当前语义
- 如果 `hasInteractiveViewport == false`
- 会调用 `CancelSceneViewportTransformGizmoFrame(...)`
- `overlayFrameData` 回退到 `emptyOverlayFrameData`
- 返回的 `overlay``activeGizmoKind``gizmoActive` 都保持空状态
- 如果存在交互视口:
-`viewportHostService` 读取当前 `SceneViewOverlayData`
- 调用 `RefreshAndSubmitSceneViewportTransformGizmoFrame(...)`
- 记录最新的 frame state、overlay submission 和 HUD overlay
- `overlayFrameData` 改为 host service 当前返回的 editor overlay frame data
## 真实使用位置
- `SceneViewPanel::Render()` 当前会在解析 hover interaction 之前调用这里,先把 overlay、HUD 和 gizmo frame 刷新到一致状态。
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前覆盖了交互/非交互两条主要路径。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportInteractionFrameState](SceneViewportInteractionFrameState.md)
- [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md)
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)

View File

@@ -0,0 +1,29 @@
# BuildSceneViewportInteractionResolveRequest
把当前帧状态和视口几何打包成 interaction resolver 输入。
```cpp
SceneViewportInteractionResolveRequest BuildSceneViewportInteractionResolveRequest(
const SceneViewportInteractionFrameState& frameState,
const SceneViewportFrameGeometry& geometry,
const ImVec2& viewportMin,
const ImVec2& viewportMax,
const ImVec2& absoluteMousePosition);
```
## 当前语义
- 它不会重新做命中测试,只负责组装请求对象。
- `overlayFrameData``hudOverlay` 都直接引用 `frameState` 里的现成结果。
- `viewportSize``localMousePosition` 直接复用 `geometry`
- `viewportMin / viewportMax / absoluteMousePosition` 则为 HUD hit-test 提供绝对坐标输入。
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了 request 字段复制是否正确。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportInteractionFrameState](SceneViewportInteractionFrameState.md)
- [SceneViewportInteractionResolveRequest](../SceneViewportInteractionResolver/SceneViewportInteractionResolveRequest.md)
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)

View File

@@ -0,0 +1,38 @@
# BuildSceneViewportToolState
根据工具模式、pivot 模式和坐标空间模式构建当前帧工具状态。
```cpp
SceneViewportToolState BuildSceneViewportToolState(
SceneViewportToolMode toolMode,
SceneViewportPivotMode pivotMode,
SceneViewportTransformSpaceMode transformSpaceMode);
```
## 参数
- `toolMode` - 当前激活的 Scene View 工具模式。
- `pivotMode` - 当前 gizmo pivot 模式。
- `transformSpaceMode` - 当前 gizmo 坐标空间模式。
## 当前语义
- `ViewMove` 会打开 `usingViewMoveTool`,但不会打开 transform gizmo。
- `Move` / `Rotate` / `Scale` 分别只显示对应 gizmo。
- `Transform` 会同时把三类 gizmo 都标记为可见,并设置 `usingTransformTool = true`
- `Center` 会映射到 `useCenterPivot = true`
- `Local` 会映射到 `localSpace = true`
- 最终还会调用 `BuildSceneViewportTransformGizmoFrameOptions(...)` 生成 `gizmoFrameOptions`
## 真实使用位置
- `SceneViewPanel::Render()` 当前会在处理完工具栏点击和快捷键后立即调用这里,作为 gizmo frame 刷新前的第一步状态汇总。
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了 move 模式和 transform 模式的字段组合。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportToolState](SceneViewportToolState.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)

View File

@@ -0,0 +1,34 @@
# RefreshAndDrawSceneViewportPresentation
刷新 Scene View 帧尾段的 transform gizmo presentation并绘制 HUD overlay。
```cpp
void RefreshAndDrawSceneViewportPresentation(
const SceneViewportPresentationRequest& request);
```
## 当前语义
- 如果 `request.IsValid() == false``request.hasInteractiveViewport == false`,直接返回。
- 否则会先从 `request.viewportHostService` 读取当前 `SceneViewportOverlayData`
- 然后调用 `RefreshAndSubmitSceneViewportTransformGizmoFrame(...)`,把最新 overlay、viewport geometry 和 gizmo frame options 再次提交给 transform gizmo coordinator。
- 最后调用 `DrawSceneViewportHudOverlay(...)`,把同一份 overlay 转成 HUD overlay 并画到 `request.drawList` 上。
## 关键边界
- 这是 `SceneViewPanel` 在提交 `SceneViewportInput` 之后的最终 presentation helper用来让 gizmo overlay 跟上最新相机状态。
- 它不重新做 interaction resolve也不处理 gizmo begin / update / end 生命周期命令。
- `drawList` 允许为空;当前实现仍会刷新 gizmo frame只是 HUD overlay 绘制阶段会直接 no-op。
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前覆盖了:
- 非交互 viewport 时不会提交 gizmo overlay
- 交互 viewport 且 `drawList == nullptr` 时仍会刷新 gizmo frame
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportPresentationRequest](SceneViewportPresentationRequest.md)
- [RefreshAndSubmitSceneViewportTransformGizmoFrame](../SceneViewportTransformGizmoCoordinator/RefreshAndSubmitSceneViewportTransformGizmoFrame.md)
- [DrawSceneViewportHudOverlay](../SceneViewportHudOverlay/DrawSceneViewportHudOverlay.md)

View File

@@ -0,0 +1,28 @@
# SceneViewportFrameGeometry
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportInteractionFrame.h`
**描述**: 描述当前 Scene View 单帧交互使用的局部几何输入。
## 字段
| 字段 | 说明 |
|------|------|
| `viewportSize` | 当前 viewport 的本地尺寸。 |
| `localMousePosition` | 鼠标相对于 viewport 左上角的本地坐标。 |
## 当前语义
- 这是 [BuildSceneViewportFrameGeometry](BuildSceneViewportFrameGeometry.md) 的输出结构。
- 它把 ImGui 的绝对屏幕坐标输入翻译成后续 gizmo refresh、interaction resolve 和 HUD hit-test 都能直接消费的局部几何数据。
- `SceneViewPanel` 会把它同时传给 gizmo frame 刷新流程和 interaction resolve request 组装流程。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [BuildSceneViewportFrameGeometry](BuildSceneViewportFrameGeometry.md)
- [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md)

View File

@@ -0,0 +1,57 @@
# SceneViewportInteractionFrame
**命名空间**: `XCEngine::Editor`
**类型**: `structs + free functions`
**源文件**: `editor/src/Viewport/SceneViewportInteractionFrame.h`
**描述**: 把 Scene View 单帧交互与 presentation 尾段所需的工具模式、视口几何、overlay 数据、焦点决策和 gizmo/HUD presentation 收口成可复用 helper。
## 概览
`SceneViewportInteractionFrame.h` 位于 `SceneViewPanel` 与 gizmo / overlay / interaction-resolver 之间。它解决的不是“如何命中交互”,而是“这一帧 Scene View 交互前后,需要复用哪些装配与收口步骤”。
当前它主要负责五件事:
1. 根据工具模式生成当前帧的 gizmo 开关和 frame options。
2. 把 ImGui 视口矩形和鼠标位置整理成统一的局部几何输入。
3.`IViewportHostService` 拉取 overlay 与 gizmo frame 更新结果,并组装成可供后续 interaction resolve 使用的 frame state。
4. 把 tool command、interaction action 与 navigation begin 标志折叠成统一的 Scene View focus 决策。
5. 在本帧尾段刷新最新 gizmo presentation并绘制 HUD overlay。
## 公开结构与函数
| 成员 | 说明 |
|------|------|
| [SceneViewportToolState](SceneViewportToolState.md) | 当前工具模式翻译后的 gizmo 与 pivot/space 状态。 |
| [BuildSceneViewportToolState](BuildSceneViewportToolState.md) | 从 tool/pivot/space 三组枚举构建工具状态。 |
| [SceneViewportFrameGeometry](SceneViewportFrameGeometry.md) | 当前视口尺寸和本地鼠标坐标。 |
| [BuildSceneViewportFrameGeometry](BuildSceneViewportFrameGeometry.md) | 从 ImGui 输入构建 frame geometry。 |
| [SceneViewportInteractionFrameState](SceneViewportInteractionFrameState.md) | 当前帧 overlay、gizmo 更新结果和 HUD 数据。 |
| [BuildSceneViewportInteractionFrameState](BuildSceneViewportInteractionFrameState.md) | 组装单帧交互状态。 |
| [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md) | 把 frame state 与视口几何打包成 resolver 输入。 |
| [ShouldFocusSceneViewportAfterInteraction](ShouldFocusSceneViewportAfterInteraction.md) | 折叠工具切换、点击动作与导航起始事件,决定是否聚焦 Scene View。 |
| [SceneViewportPresentationRequest](SceneViewportPresentationRequest.md) | 描述单帧尾段 gizmo/HUD presentation 所需的输入。 |
| [RefreshAndDrawSceneViewportPresentation](RefreshAndDrawSceneViewportPresentation.md) | 刷新最终 gizmo frame 并绘制 HUD overlay。 |
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了:
- 工具模式到 gizmo 显示状态的映射。
- 视口尺寸与本地鼠标坐标的构造。
- 非交互视口时如何回退到空 overlay frame。
- 交互视口时如何消费 `IViewportHostService` 的 overlay 与 gizmo submission。
- interaction resolve request 是否正确复制 frame-state 与几何输入。
- focus helper 是否正确收口 tool command、click action 与 navigation begin 条件。
- presentation helper 是否会跳过非交互视口,并在 `drawList == nullptr` 时仍刷新 gizmo frame。
## 相关文档
- [Viewport](../Viewport.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)
- [SceneViewportChrome](../SceneViewportChrome/SceneViewportChrome.md)
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)

View File

@@ -0,0 +1,37 @@
# SceneViewportInteractionFrameState
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportInteractionFrame.h`
**描述**: 描述 Scene View 当前帧已经准备好的 overlay、gizmo 和 HUD 状态包。
## 关键字段
- `hasInteractiveViewport`:这一帧是否存在可交互 viewport。
- `overlay`:当前 scene view overlay 数据。
- `gizmoFrameUpdate` / `gizmoFrameState`:当前帧 transform gizmo 刷新结果与生命周期状态。
- `overlayFrameData`:当前帧 editor overlay primitive 数据来源。
- `activeGizmoKind`:当前处于激活态的 gizmo 类型。
- `gizmoActive`:当前是否已有 gizmo 占用交互。
- `hudOverlay`HUD overlay 数据。
## 当前语义
- 这是 [BuildSceneViewportInteractionFrameState](BuildSceneViewportInteractionFrameState.md) 的输出结构。
- 它是 `SceneViewPanel` 在“准备阶段”和“interaction resolve 阶段”之间传递的单帧状态包。
- 后续的 [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md) 会把其中的 overlay、HUD 和局部几何数据重新打包成 resolver 输入。
## 当前实现边界
- 它不直接保存最终 hover 命中结果;那是 interaction resolver 的职责。
- 它也不直接驱动相机导航;导航状态由 [SceneViewportNavigation](../SceneViewportNavigation/SceneViewportNavigation.md) 维护。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [BuildSceneViewportInteractionFrameState](BuildSceneViewportInteractionFrameState.md)
- [BuildSceneViewportInteractionResolveRequest](BuildSceneViewportInteractionResolveRequest.md)
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)

View File

@@ -0,0 +1,36 @@
# SceneViewportPresentationRequest
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportInteractionFrame.h`
**描述**: 描述 Scene View 单帧尾段 gizmo/HUD presentation 所需的输入集合。
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `context` | `IEditorContext*` | 当前 editor 上下文。 |
| `viewportHostService` | `IViewportHostService*` | Scene View overlay 与 gizmo 提交宿主。 |
| `hasInteractiveViewport` | `bool` | 当前帧是否存在可交互 viewport。 |
| `geometry` | `SceneViewportFrameGeometry` | 当前 viewport 尺寸与本地鼠标坐标。 |
| `gizmoFrameOptions` | `SceneViewportTransformGizmoFrameOptions` | 当前 gizmo 刷新配置。 |
| `moveGizmo` / `rotateGizmo` / `scaleGizmo` | gizmo 指针 | 三类 gizmo 实例。 |
| `drawList` | `ImDrawList*` | HUD overlay 的目标绘制列表。 |
| `viewportMin` / `viewportMax` | `ImVec2` | HUD overlay 的 viewport 绝对矩形。 |
## 当前语义
- 这是 [RefreshAndDrawSceneViewportPresentation](RefreshAndDrawSceneViewportPresentation.md) 的输入结构。
- `IsValid()` 当前要求 `context``viewportHostService``moveGizmo``rotateGizmo``scaleGizmo` 全部非空。
- `drawList` 不属于 `IsValid()` 的必需条件;当前实现允许 `drawList == nullptr`,此时 gizmo frame 仍会刷新HUD 绘制则会在 `DrawSceneViewportHudOverlay(...)` 内部直接返回。
- `hasInteractiveViewport == false` 时,这份请求依然可以是“有效”的,但 presentation helper 会整体 no-op。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [RefreshAndDrawSceneViewportPresentation](RefreshAndDrawSceneViewportPresentation.md)
- [BuildSceneViewportFrameGeometry](BuildSceneViewportFrameGeometry.md)
- [BuildSceneViewportToolState](BuildSceneViewportToolState.md)

View File

@@ -0,0 +1,35 @@
# SceneViewportToolState
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportInteractionFrame.h`
**描述**: 描述当前 Scene View 工具模式翻译后的 gizmo、pivot 和坐标空间状态。
## 关键字段
- `usingViewMoveTool`:当前是否处于 `ViewMove` 导航工具。
- `usingTransformTool`:当前是否处于联合 `Transform` 工具。
- `showingMoveGizmo` / `showingRotateGizmo` / `showingScaleGizmo`:当前帧三类 gizmo 是否应被显示与刷新。
- `useCenterPivot`:当前是否使用中心 pivot而不是对象 pivot。
- `localSpace`:当前是否使用局部坐标空间。
- `gizmoFrameOptions`:进一步传给 transform gizmo frame builder / coordinator 的聚合选项。
## 当前语义
- 这是 [BuildSceneViewportToolState](BuildSceneViewportToolState.md) 的输出结构。
- `SceneViewPanel` 会先根据工具栏、快捷键、pivot 开关和 global/local 开关生成这份结构,再把其中的 `gizmoFrameOptions` 交给 gizmo frame 刷新流程。
- `Transform` 模式并不是第四套独立 gizmo而是同时打开 move / rotate / scale 三类 gizmo 的聚合模式。
## 当前实现边界
- 这里不保存拖拽生命周期状态,也不描述当前 hover/selection 命中结果。
- 它只负责“这一帧应该以什么工具配置刷新 gizmo”真正的交互命中和生命周期控制仍在后续步骤完成。
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [BuildSceneViewportToolState](BuildSceneViewportToolState.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)

View File

@@ -0,0 +1,36 @@
# ShouldFocusSceneViewportAfterInteraction
把工具切换、点击动作和导航起始事件折叠成 Scene View 聚焦决策。
```cpp
bool ShouldFocusSceneViewportAfterInteraction(
bool toolCommandTriggered,
const SceneViewportInteractionActions& interactionActions,
const SceneViewportNavigationUpdate& navigationUpdate);
```
## 当前语义
- 只要 `toolCommandTriggered == true`,就返回 `true`
- 只要 `interactionActions.HasClickAction() == true`,就返回 `true`
- 只要 `navigationUpdate.beginLookDrag``navigationUpdate.beginPanDrag` 为真,就返回 `true`
- 它不关心 hover-only 状态,也不直接调用 `ImGui::SetWindowFocus()`;真正的聚焦动作仍由 `SceneViewPanel::Render()` 执行。
## 真实使用位置
- `SceneViewPanel::Render()` 当前会在更新导航状态之后调用这里,再决定是否执行 `ImGui::SetWindowFocus()`
## 测试覆盖
`tests/Editor/test_scene_viewport_interaction_frame.cpp` 当前验证了:
- 空 tool / 空 action / 空 navigation 时返回 `false`
- tool command 触发时返回 `true`
- click action 存在时返回 `true`
- navigation begin 标志出现时返回 `true`
## 相关文档
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame.md)
- [SceneViewportInteractionActions](../SceneViewportInteractionActions/SceneViewportInteractionActions.md)
- [SceneViewportNavigationUpdate](../SceneViewportNavigation/SceneViewportNavigationUpdate.md)
- [SceneViewPanel::Render](../../panels/SceneViewPanel/Render.md)

View File

@@ -0,0 +1,35 @@
# BuildSceneViewportCaptureFlags
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
SceneViewportCaptureFlags BuildSceneViewportCaptureFlags(
const SceneViewportCaptureRequest& request);
```
## 作用
根据导航状态和 gizmo 活动状态,生成下一帧 ImGui 输入捕获标志。
## 当前实现行为
- `captureMouse` 在以下任一条件满足时为 `true`
- `state.lookDragging`
- `state.panDragging`
- `moveGizmoActive`
- `rotateGizmoActive`
- `scaleGizmoActive`
- `captureKeyboard` 当前只在 `state.lookDragging` 时为 `true`
`tests/Editor/test_scene_viewport_navigation.cpp` 当前验证了 look drag 与 gizmo active 两类典型输入。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportCaptureRequest](SceneViewportCaptureRequest.md)

View File

@@ -0,0 +1,39 @@
# BuildSceneViewportInput
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
SceneViewportInput BuildSceneViewportInput(const SceneViewportInputBuildRequest& request);
```
## 作用
把 ImGui 层输入快照翻译成 `IViewportHostService::UpdateSceneViewInput(...)` 需要的 `SceneViewportInput`
## 当前实现行为
- `viewportSize``deltaTime` 直接透传。
- `focused` 只要满足以下任一条件就会置为 `true`
- `viewportFocused`
- `state.lookDragging`
- `state.panDragging`
- `mouseWheel` 只有在 `viewportHovered && !state.lookDragging` 时才透传;否则清零。
- `flySpeedDelta` 只有在 `viewportHovered && state.lookDragging` 时才透传;否则清零。
- `looking` 取自 `state.lookDragging``panning` 取自 `state.panDragging``orbiting` 当前固定为 `false`
- `focusSelectionRequested` 需要 `focused == true``wantTextInput == false``focusSelectionKeyPressed == true`
- 只有在 `state.lookDragging && !wantTextInput` 时,`moveForward / moveRight / moveUp` 等飞行移动轴才会写入。
- 只有在 look 或 pan drag 活跃时,`mouseDelta` 才会透传。
`tests/Editor/test_scene_viewport_navigation.cpp` 当前验证了滚轮、飞行速度调节、焦点请求、移动轴和鼠标位移的映射。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportInputBuildRequest](SceneViewportInputBuildRequest.md)
- [IViewportHostService](../IViewportHostService/IViewportHostService.md)

View File

@@ -0,0 +1,38 @@
# BuildSceneViewportToolShortcutAction
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
SceneViewportToolShortcutAction BuildSceneViewportToolShortcutAction(
const SceneViewportToolShortcutRequest& request);
```
## 作用
把 Scene View 工具快捷键输入翻译成工具切换动作和相应的 gizmo cancel 策略。
## 当前实现行为
- 如果 [CanUseSceneViewportToolShortcut](CanUseSceneViewportToolShortcut.md) 返回 `false`,函数直接返回默认空动作。
- 当前按固定优先级检查按键:
1. `pressedViewMove`
2. `pressedMove`
3. `pressedRotate`
4. `pressedScale`
- 一旦命中,会设置:
- `targetTool`
- `triggered = true`
- 与目标工具不兼容的 `cancel*Gizmo` 标志
`tests/Editor/test_scene_viewport_navigation.cpp` 当前验证了 view-move 和 rotate 的映射结果。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportToolShortcutAction](SceneViewportToolShortcutAction.md)

View File

@@ -0,0 +1,38 @@
# CanResolveSceneViewportInteraction
判断当前帧是否允许进入 Scene View 的 overlay / HUD 交互命中解析。
```cpp
bool CanResolveSceneViewportInteraction(
bool hasInteractiveViewport,
bool viewportHovered,
bool usingViewMoveTool,
const SceneViewportNavigationState& navigationState,
bool gizmoActive);
```
## 当前语义
当前只有在以下条件全部满足时才返回 `true`
- `hasInteractiveViewport`
- `viewportHovered`
- `!usingViewMoveTool`
- `!navigationState.lookDragging`
- `!navigationState.panDragging`
- `!gizmoActive`
## 设计说明
- 这意味着当前实现会在 view-move 导航、任意导航拖拽和 gizmo active 期间屏蔽新的 hover / click 解析。
- 它相当于 `SceneViewPanel` 在调用 [ResolveSceneViewportInteraction](../SceneViewportInteractionResolver/ResolveSceneViewportInteraction.md) 前的一层统一守卫。
## 测试覆盖
`tests/Editor/test_scene_viewport_navigation.cpp` 当前覆盖了 hover、导航和 gizmo active 对返回值的影响。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportNavigationState](SceneViewportNavigationState.md)
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
- [SceneViewPanel::Render](../../panels/SceneViewPanel/Render.md)

View File

@@ -0,0 +1,32 @@
# CanUseSceneViewportToolShortcut
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
bool CanUseSceneViewportToolShortcut(const SceneViewportToolShortcutRequest& request);
```
## 作用
判断当前帧是否允许处理 Scene View 工具快捷键。
## 当前实现行为
- 只要满足以下任一条件,就返回 `false`
- `wantTextInput == true`
- `lookDragging == true`
- `panDragging == true`
- 其余情况返回 `true`
这意味着当前实现会在文本输入或任何导航拖拽期间彻底屏蔽 `Q/W/E/R` 工具切换。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [BuildSceneViewportToolShortcutAction](BuildSceneViewportToolShortcutAction.md)

View File

@@ -0,0 +1,32 @@
# IsSceneViewportPanDragButtonDown
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
bool IsSceneViewportPanDragButtonDown(
const SceneViewportNavigationRequest& request,
int button);
```
## 作用
根据 `panDragButton` 的值,判断当前 pan drag 绑定的鼠标键是否仍然按下。
## 当前实现行为
- `ImGuiMouseButton_Left` 对应 `request.leftMouseDown`
- `ImGuiMouseButton_Right` 对应 `request.rightMouseDown`
- 其余值都按中键处理,返回 `request.middleMouseDown`
当前导航状态机只会把左键或中键写入 `panDragButton`,这里的默认分支是防御式兜底。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md)

View File

@@ -0,0 +1,28 @@
# SceneViewportCaptureFlags
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
**描述**: 描述当前帧是否需要让 Scene View 请求捕获鼠标和键盘输入。
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `captureMouse` | `bool` | 是否应让 ImGui 在下一帧继续捕获鼠标。 |
| `captureKeyboard` | `bool` | 是否应让 ImGui 在下一帧继续捕获键盘。 |
## 当前语义
- `captureMouse` 的范围更宽:只要处于 look drag、pan drag或任意 gizmo 还在 active就会被置为 `true`
- `captureKeyboard` 更保守:当前只在 look drag 期间捕获键盘。
- `SceneViewPanel` 当前会把它翻译成 `ImGui::SetNextFrameWantCaptureMouse/Keyboard(...)`
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportCaptureRequest](SceneViewportCaptureRequest.md)
- [BuildSceneViewportCaptureFlags](BuildSceneViewportCaptureFlags.md)

View File

@@ -0,0 +1,26 @@
# SceneViewportCaptureRequest
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `state` | `SceneViewportNavigationState` | 当前导航状态。 |
| `moveGizmoActive` | `bool` | move gizmo 是否正在拖拽。 |
| `rotateGizmoActive` | `bool` | rotate gizmo 是否正在拖拽。 |
| `scaleGizmoActive` | `bool` | scale gizmo 是否正在拖拽。 |
## 当前用法
- `SceneViewPanel::Render()` 当前在 gizmo lifecycle 更新后构造它。
- [BuildSceneViewportCaptureFlags](BuildSceneViewportCaptureFlags.md) 根据它决定是否调用 `ImGui::SetNextFrameWantCaptureMouse/Keyboard(true)`
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportCaptureFlags](SceneViewportCaptureFlags.md)

View File

@@ -0,0 +1,38 @@
# SceneViewportInputBuildRequest
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `state` | `SceneViewportNavigationState` | 当前导航状态。 |
| `viewportSize` | `ImVec2` | 当前 viewport 尺寸。 |
| `mouseDelta` | `ImVec2` | 本帧鼠标位移。 |
| `mouseWheel` | `float` | 本帧滚轮增量。 |
| `deltaTime` | `float` | 帧间隔。 |
| `viewportHovered` | `bool` | viewport 是否悬停。 |
| `viewportFocused` | `bool` | viewport 是否已有焦点。 |
| `wantTextInput` | `bool` | ImGui 是否需要文本输入。 |
| `fastMove` | `bool` | 是否启用快速移动。当前由 `Shift` 透传。 |
| `focusSelectionKeyPressed` | `bool` | 是否请求聚焦当前选择。 |
| `moveForwardKeyDown` | `bool` | 前进键是否按下。 |
| `moveBackwardKeyDown` | `bool` | 后退键是否按下。 |
| `moveRightKeyDown` | `bool` | 右移键是否按下。 |
| `moveLeftKeyDown` | `bool` | 左移键是否按下。 |
| `moveUpKeyDown` | `bool` | 上移键是否按下。 |
| `moveDownKeyDown` | `bool` | 下移键是否按下。 |
## 当前用法
- `SceneViewPanel::Render()` 当前用 ImGui IO、窗口焦点和键盘状态填充它。
- [BuildSceneViewportInput](BuildSceneViewportInput.md) 会把它翻译成宿主服务消费的 `SceneViewportInput`
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [BuildSceneViewportInput](BuildSceneViewportInput.md)

View File

@@ -0,0 +1,58 @@
# SceneViewportNavigation
**命名空间**: `XCEngine::Editor`
**类型**: `header-helper + structs`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
**描述**: Scene View 的 header-only 导航与输入组装层负责工具快捷键、look/pan drag 状态机、ImGui capture 标志以及 `SceneViewportInput` 构造。
## 概述
`SceneViewportNavigation.h` 解决的是 `SceneViewPanel` 中那部分与渲染无关、但每帧都要稳定重复执行的输入规则:
- 工具快捷键何时可用
- 右键 look drag / 中键或 view-move 左键 pan drag 如何开始和结束
- 当前是否应该拦截鼠标与键盘
- 如何把 ImGui 输入快照翻译成 `IViewportHostService::UpdateSceneViewInput(...)` 需要的 `SceneViewportInput`
当前 `SceneViewPanel::Render()` 会直接消费这些 helper而不是自己手拼多个拖拽布尔位。
## 公开类型与函数
| 成员 | 说明 |
|------|------|
| [SceneViewportToolShortcutRequest](SceneViewportToolShortcutRequest.md) | 工具快捷键输入快照。 |
| [SceneViewportToolShortcutAction](SceneViewportToolShortcutAction.md) | 快捷键解析结果。 |
| [CanUseSceneViewportToolShortcut](CanUseSceneViewportToolShortcut.md) | 判断当前是否允许切换工具。 |
| [BuildSceneViewportToolShortcutAction](BuildSceneViewportToolShortcutAction.md) | 把快捷键输入翻译成目标工具和取消策略。 |
| [SceneViewportNavigationState](SceneViewportNavigationState.md) | 持久化的导航拖拽状态。 |
| [SceneViewportNavigationRequest](SceneViewportNavigationRequest.md) | 导航状态机输入。 |
| [SceneViewportNavigationUpdate](SceneViewportNavigationUpdate.md) | 导航状态机输出。 |
| [ShouldBeginSceneViewportNavigationDrag](ShouldBeginSceneViewportNavigationDrag.md) | 判断某类导航拖拽是否可开始。 |
| [IsSceneViewportPanDragButtonDown](IsSceneViewportPanDragButtonDown.md) | 判断当前 pan drag 绑定的鼠标键是否仍按下。 |
| [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md) | 更新 look / pan drag 状态机。 |
| [SceneViewportCaptureRequest](SceneViewportCaptureRequest.md) | ImGui capture 计算输入。 |
| [SceneViewportCaptureFlags](SceneViewportCaptureFlags.md) | 是否捕获鼠标 / 键盘。 |
| [BuildSceneViewportCaptureFlags](BuildSceneViewportCaptureFlags.md) | 计算 capture 标志。 |
| [CanResolveSceneViewportInteraction](CanResolveSceneViewportInteraction.md) | 判断当前帧是否允许进行 Scene View 交互命中解析。 |
| [SceneViewportInputBuildRequest](SceneViewportInputBuildRequest.md) | 组装 `SceneViewportInput` 所需的输入快照。 |
| [BuildSceneViewportInput](BuildSceneViewportInput.md) | 构造交给宿主服务的 `SceneViewportInput`。 |
## 测试锚点
`tests/Editor/test_scene_viewport_navigation.cpp` 当前覆盖了:
- 快捷键在文本输入或导航拖拽期间的屏蔽逻辑
- `Q/W/E/R` 映射与 gizmo cancel 标志
- look drag / pan drag 的开始与结束
- capture 标志的生成
- `SceneViewportInput` 的滚轮、焦点、移动轴与鼠标位移映射
- 交互解析门禁条件
## 相关文档
- [Viewport](../Viewport.md)
- [SceneViewportEditorModes](../SceneViewportEditorModes/SceneViewportEditorModes.md)
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)

View File

@@ -0,0 +1,33 @@
# SceneViewportNavigationRequest
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `state` | `SceneViewportNavigationState` | 进入本帧前的导航状态。 |
| `hasInteractiveViewport` | `bool` | 当前是否存在可交互 viewport。 |
| `viewportHovered` | `bool` | 当前鼠标是否悬停在 viewport 内容区域。 |
| `usingViewMoveTool` | `bool` | 当前工具是否为 `ViewMove`。 |
| `gizmoActive` | `bool` | 是否已有 gizmo 正在拖拽。 |
| `clickedLeft` | `bool` | 本帧左键是否点击。 |
| `clickedRight` | `bool` | 本帧右键是否点击。 |
| `clickedMiddle` | `bool` | 本帧中键是否点击。 |
| `leftMouseDown` | `bool` | 左键当前是否按下。 |
| `rightMouseDown` | `bool` | 右键当前是否按下。 |
| `middleMouseDown` | `bool` | 中键当前是否按下。 |
## 当前用法
- `SceneViewPanel::Render()` 当前直接从 `ViewportPanelContentResult``ImGui::IsMouseDown(...)` 填充它。
- [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md) 会把这些离散输入归并成稳定的导航状态机更新。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportNavigationUpdate](SceneViewportNavigationUpdate.md)

View File

@@ -0,0 +1,26 @@
# SceneViewportNavigationState
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `lookDragging` | `bool` | 当前是否处于右键 look drag。 |
| `panDragging` | `bool` | 当前是否处于 pan drag。 |
| `panDragButton` | `int` | 当前 pan drag 绑定的鼠标键。默认值是 `ImGuiMouseButton_Middle`。 |
## 当前语义
- `SceneViewPanel` 把它作为成员 `m_navigationState` 持久化保存。
- 当前实现保证 look drag 与 pan drag 互斥。
- `panDragButton` 只在 pan drag 开始时切到左键或中键;结束时会重置回中键默认值。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md)

View File

@@ -0,0 +1,28 @@
# SceneViewportNavigationUpdate
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `state` | `SceneViewportNavigationState` | 更新后的导航状态。 |
| `beginLookDrag` | `bool` | 当前帧是否开始 look drag。 |
| `beginPanDrag` | `bool` | 当前帧是否开始 pan drag。 |
| `beginLeftPanDrag` | `bool` | 当前帧是否以左键开始 pan drag。 |
| `beginMiddlePanDrag` | `bool` | 当前帧是否以中键开始 pan drag。 |
## 当前语义
- `beginPanDrag``beginLeftPanDrag || beginMiddlePanDrag` 的合成位。
- `SceneViewPanel::Render()` 当前会把这些 begin 标志连同 tool command 与 interaction action 一起交给 `ShouldFocusSceneViewportAfterInteraction(...)`,再决定是否调用 `ImGui::SetWindowFocus()`
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md)
- [ShouldFocusSceneViewportAfterInteraction](../SceneViewportInteractionFrame/ShouldFocusSceneViewportAfterInteraction.md)

View File

@@ -0,0 +1,31 @@
# SceneViewportToolShortcutAction
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `targetTool` | `SceneViewportToolMode` | 快捷键命中的目标工具。默认值是 `Move`。 |
| `triggered` | `bool` | 当前帧是否真的形成了工具切换动作。 |
| `cancelMoveGizmo` | `bool` | 切换时是否应取消 move gizmo 正在进行的拖拽。 |
| `cancelRotateGizmo` | `bool` | 切换时是否应取消 rotate gizmo 正在进行的拖拽。 |
| `cancelScaleGizmo` | `bool` | 切换时是否应取消 scale gizmo 正在进行的拖拽。 |
## 当前语义
- `HasAction()` 只检查 `triggered`
- 当前实现里:
- `ViewMove` 会取消三类 gizmo drag。
- `Move` 会取消 rotate / scale drag。
- `Rotate` 会取消 move / scale drag。
- `Scale` 会取消 move / rotate drag。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [BuildSceneViewportToolShortcutAction](BuildSceneViewportToolShortcutAction.md)

View File

@@ -0,0 +1,29 @@
# SceneViewportToolShortcutRequest
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `wantTextInput` | `bool` | ImGui 当前是否需要文本输入。 |
| `lookDragging` | `bool` | 当前是否处于右键 look drag。 |
| `panDragging` | `bool` | 当前是否处于 pan drag。 |
| `pressedViewMove` | `bool` | 是否触发 view-move 快捷键。 |
| `pressedMove` | `bool` | 是否触发 move 快捷键。 |
| `pressedRotate` | `bool` | 是否触发 rotate 快捷键。 |
| `pressedScale` | `bool` | 是否触发 scale 快捷键。 |
## 当前用法
- `SceneViewPanel::Render()` 当前用 `ImGui::IsKeyPressed(ImGuiKey_Q/W/E/R, false)` 填充这些字段。
- `CanUseSceneViewportToolShortcut(...)` 和 [BuildSceneViewportToolShortcutAction](BuildSceneViewportToolShortcutAction.md) 直接消费它。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportToolShortcutAction](SceneViewportToolShortcutAction.md)

View File

@@ -0,0 +1,41 @@
# ShouldBeginSceneViewportNavigationDrag
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
bool ShouldBeginSceneViewportNavigationDrag(
bool hasInteractiveViewport,
bool hovered,
bool activeDrag,
bool otherDrag,
bool gizmoActive,
bool clicked);
```
## 作用
判断某一类 Scene View 导航拖拽在当前帧是否允许开始。
## 当前实现行为
当前返回条件是以下布尔位全部满足:
- `hasInteractiveViewport`
- `hovered`
- `!activeDrag`
- `!otherDrag`
- `!gizmoActive`
- `clicked`
因此它只负责最小门禁判断,不区分左键 pan、右键 look 还是中键 pan 的具体来源。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [UpdateSceneViewportNavigationState](UpdateSceneViewportNavigationState.md)

View File

@@ -0,0 +1,36 @@
# UpdateSceneViewportNavigationState
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportNavigation.h`
## 签名
```cpp
SceneViewportNavigationUpdate UpdateSceneViewportNavigationState(
const SceneViewportNavigationRequest& request);
```
## 作用
更新 Scene View 的 look drag / pan drag 状态机。
## 当前实现行为
- 左键 pan drag 只有在 `usingViewMoveTool == true` 时才允许开始。
- 右键点击会尝试开始 look drag。
- 中键点击会尝试开始 pan drag。
- 一旦开始 look drag会强制清掉 `panDragging`
- 一旦开始 pan drag会强制清掉 `lookDragging`,并把 `panDragButton` 记成左键或中键。
- 如果 `lookDragging == true` 但右键已松开,会结束 look drag。
- 如果 `panDragging == true` 且当前绑定鼠标键已松开,会结束 pan drag并把 `panDragButton` 重置为 `ImGuiMouseButton_Middle`
`tests/Editor/test_scene_viewport_navigation.cpp` 当前验证了 look drag / pan drag 的开始与释放收尾逻辑。
## 相关文档
- [SceneViewportNavigation](SceneViewportNavigation.md)
- [SceneViewportNavigationState](SceneViewportNavigationState.md)
- [SceneViewportNavigationUpdate](SceneViewportNavigationUpdate.md)

View File

@@ -0,0 +1,35 @@
# BuildSceneViewportTransformGizmoOverlayState
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/SceneViewportOverlayHandleBuilder.h`
## 签名
```cpp
SceneViewportTransformGizmoOverlayState BuildSceneViewportTransformGizmoOverlayState(
const SceneViewportTransformGizmoHandleBuildInputs& inputs);
```
## 作用
把轻量的 gizmo handle build inputs 压缩成可缓存、可提交的 `SceneViewportTransformGizmoOverlayState`
## 当前实现行为
- 如果 `inputs.moveGizmo != nullptr`
-`hasMoveGizmo = true`
- 拷贝 move draw data
- 写入 `moveEntityId`
- rotate 和 scale 分支遵循同样规则。
- 函数不会根据 `visible` 位过滤 gizmo可见性判断留给 `SceneViewportTransformGizmoOverlayState::HasAnyVisibleGizmo()` 或下游 provider / pass。
当前 `SceneViewportTransformGizmoCoordinator::BuildSceneViewportTransformGizmoOverlaySubmission(...)` 会直接调用它构造本帧 overlay state。
## 相关文档
- [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder.md)
- [SceneViewportTransformGizmoHandleBuildInputs](SceneViewportTransformGizmoHandleBuildInputs.md)
- [SceneViewportTransformGizmoOverlayState](SceneViewportTransformGizmoOverlayState.md)

View File

@@ -2,105 +2,42 @@
**命名空间**: `XCEngine::Editor` **命名空间**: `XCEngine::Editor`
**类型**: `utility-header` **类型**: `header-helper + structs`
**源文件**: `editor/src/Viewport/SceneViewportOverlayHandleBuilder.h` **源文件**: `editor/src/Viewport/SceneViewportOverlayHandleBuilder.h`
**描述**: 把 move / rotate / scale gizmo 的绘制数据转换成可渲染的屏幕三角形、可命中的 overlay handle 记录,以及可跨函数传递的 gizmo overlay state **描述**: header-only helper负责把 transform gizmo overlay state 转成 canonical `SceneViewportOverlayFrameData` 里的 `screenTriangles``handleRecords`
## 概述 ## 概述
`SceneViewportOverlayHandleBuilder` 处在当前 Scene View gizmo 链路的中间层 这层 helper 解决的是“gizmo 自己的 draw data / hovered state”如何变成统一 overlay frame data 的问题
上游 gizmo 负责算出“应该画什么”;这一层再把结果整理成 当前主要入口分成三步
- `SceneViewportTransformGizmoHandleBuildInputs` - [BuildSceneViewportTransformGizmoHandleBuildInputs](BuildSceneViewportTransformGizmoHandleBuildInputs.md)
- `SceneViewportTransformGizmoOverlayState` 先把 gizmo/context 或已有 overlay state 收口成轻量输入包。
- `SceneViewportOverlayFrameData.screenTriangles` - [BuildSceneViewportTransformGizmoOverlayState](BuildSceneViewportTransformGizmoOverlayState.md)
- `SceneViewportOverlayFrameData.handleRecords` 再把输入包压缩成可提交给宿主服务缓存的 gizmo overlay state。
- [BuildSceneViewportTransformGizmoOverlayFrameData](BuildSceneViewportTransformGizmoOverlayFrameData.md)
最后把这份 state 转成 canonical `screenTriangles``handleRecords`
这样后续的 overlay 渲染和鼠标 hit test 就能共享同一套 gizmo 语义。 ## 公开类型与函数
## 当前公开内容 | 成员 | 说明 |
|------|------|
### `SceneViewportTransformGizmoHandleBuildInputs` | [SceneViewportTransformGizmoHandleBuildInputs](SceneViewportTransformGizmoHandleBuildInputs.md) | overlay 构建阶段使用的轻量输入包。 |
| [SceneViewportTransformGizmoOverlayState](SceneViewportTransformGizmoOverlayState.md) | 可提交给宿主服务的 gizmo overlay 状态。 |
把三类 gizmo draw data 和对应实体 id 聚合到一起: | [BuildSceneViewportTransformGizmoHandleBuildInputs](BuildSceneViewportTransformGizmoHandleBuildInputs.md) | 两组 overload用于从 gizmo/context 或 overlay state 构建输入包。 |
| [BuildSceneViewportTransformGizmoOverlayState](BuildSceneViewportTransformGizmoOverlayState.md) | 从轻量输入包构造可缓存的 gizmo overlay state。 |
- `moveGizmo` / `moveEntityId` | [BuildSceneViewportTransformGizmoOverlayFrameData](BuildSceneViewportTransformGizmoOverlayFrameData.md) | 生成 canonical overlay frame data。 |
- `rotateGizmo` / `rotateEntityId`
- `scaleGizmo` / `scaleEntityId`
### `SceneViewportTransformGizmoOverlayState`
把当前帧可见 gizmo 的 draw data 复制成一份可缓存状态,并提供:
- `HasAnyVisibleGizmo()`
用于让宿主服务判断这一帧是否需要把 gizmo overlay 合成进 Scene View frame data。
### 主要入口
- `BuildSceneViewportTransformGizmoHandleBuildInputs(...)`
- `BuildSceneViewportTransformGizmoOverlayState(...)`
- `AppendTransformGizmoHandleRecords(...)`
- `AppendTransformGizmoScreenTriangles(...)`
- `BuildSceneViewportTransformGizmoOverlayFrameData(...)`
## 当前语义
- move gizmo 会生成轴线、平面和箭头相关的屏幕几何与 handle 记录。
- rotate gizmo 会区分前后半环、视角环和角度填充区域。
- scale gizmo 会生成轴线、端点方块和中心统一缩放方块。
- handle 记录会写入优先级、shape、entity id、handle id 和 hit thickness 等命中参数。
`BuildSceneViewportTransformGizmoOverlayFrameData(...)` 会一次性构建:
- `screenTriangles`
- `handleRecords`
因此同一份 gizmo draw data 会同时服务于:
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) 的交互命中
- [ViewportHostService](../ViewportHostService/ViewportHostService.md) 的 Scene View overlay frame data 构建
- [SceneViewportOverlayHitTester](../SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md) 的鼠标命中
## 当前使用位置 ## 当前使用位置
当前主链路是: - `SceneViewportTransformGizmoCoordinator.cpp` 当前用它们从 gizmo frame state 构造 `SceneViewportTransformGizmoOverlaySubmission`
- `SceneViewportOverlayProviders.cpp` 当前会消费 `transformGizmoOverlayState`,再调用 `AppendTransformGizmoScreenTriangles(...)``AppendTransformGizmoHandleRecords(...)`
1. `SceneViewPanel.cpp` 构造 `SceneViewportTransformGizmoHandleBuildInputs`
2. 再转成 `SceneViewportTransformGizmoOverlayState`
3. 通过 `SetSceneViewTransformGizmoOverlayState(...)` 写回 [ViewportHostService](../ViewportHostService/ViewportHostService.md)
4. `ViewportHostService``GetSceneViewEditorOverlayFrameData(...)` / `RenderRequestedViewports(...)` 中通过 [SceneViewportOverlayBuilder](../SceneViewportOverlayBuilder/SceneViewportOverlayBuilder.md) 把它们合成进最终 frame data
5. [SceneViewportOverlayHitTester](../SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md) 再消费 `handleRecords` 做鼠标命中
## 当前 priority 语义
这层 helper 还定义了当前 Scene View 命中的 priority 常量。按源码当前值:
- scene icon: `100`
- rotate axis: `311`
- move plane: `321`
- move axis: `322`
- scale axis line: `331`
- scale axis cap: `332`
- scale uniform: `333`
这些数值不是通用协议,而是当前 Editor 对 gizmo / icon 抢输入手感的产品化调参结果。
## 当前实现边界
- 当前是 header-only helper不持有生命周期状态。
- 这里处理的是屏幕空间 overlay 和命中记录,不直接提交 GPU pass。
- 优先级和 hit thickness 仍然是当前产品体验调参值,不是通用协议。
## 相关文档 ## 相关文档
- [当前模块](../Viewport.md) - [Viewport](../Viewport.md)
- [ViewportHostService](../ViewportHostService/ViewportHostService.md) - [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md)
- [SceneViewportOverlayBuilder](../SceneViewportOverlayBuilder/SceneViewportOverlayBuilder.md) - [SceneViewportEditorOverlayData](../SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md)
- [SceneViewportOverlayHitTester](../SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md)
- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md)
- [SceneViewportRotateGizmo](../SceneViewportRotateGizmo/SceneViewportRotateGizmo.md)
- [SceneViewportScaleGizmo](../SceneViewportScaleGizmo/SceneViewportScaleGizmo.md)

View File

@@ -22,7 +22,8 @@
## 当前语义 ## 当前语义
- 这是提交给 `IViewportHostService::SetSceneViewTransformGizmoOverlayState(...)` 的 gizmo overlay state。 - 这是由 coordinator 构造并提交给 `IViewportHostService::SetSceneViewTransformGizmoOverlayState(...)` 的 gizmo overlay state。
- 它不是最终的 `SceneViewportOverlayFrameData`;当前宿主服务会把它再交给 overlay provider / handle builder 链路,重建 canonical frame data。
- `HasAnyVisibleGizmo()` 当前会结合 `has*` 与各 draw data 的 `visible` 位判断是否真有可见 gizmo。 - `HasAnyVisibleGizmo()` 当前会结合 `has*` 与各 draw data 的 `visible` 位判断是否真有可见 gizmo。
## 测试覆盖 ## 测试覆盖
@@ -32,4 +33,5 @@
## 相关文档 ## 相关文档
- [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder.md) - [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder.md)
- [BuildSceneViewportTransformGizmoOverlayState](BuildSceneViewportTransformGizmoOverlayState.md)
- [SceneViewportTransformGizmoHandleBuildInputs](SceneViewportTransformGizmoHandleBuildInputs.md) - [SceneViewportTransformGizmoHandleBuildInputs](SceneViewportTransformGizmoHandleBuildInputs.md)

View File

@@ -35,6 +35,14 @@
把 HUD 命中与 overlay handle 命中合并成统一交互结果。 把 HUD 命中与 overlay handle 命中合并成统一交互结果。
- [SceneViewportInteractionActions](SceneViewportInteractionActions/SceneViewportInteractionActions.md) - [SceneViewportInteractionActions](SceneViewportInteractionActions/SceneViewportInteractionActions.md)
把交互结果折叠成 hover / click action并分发 selection / orientation 对齐。 把交互结果折叠成 hover / click action并分发 selection / orientation 对齐。
- [SceneViewportEditorModes](SceneViewportEditorModes/SceneViewportEditorModes.md)
收口工具模式、pivot 模式与变换空间模式枚举。
- [SceneViewportInteractionFrame](SceneViewportInteractionFrame/SceneViewportInteractionFrame.md)
组装每帧 tool state、frame geometry、interaction frame state并收口焦点决策与最终 presentation helper。
- [SceneViewportNavigation](SceneViewportNavigation/SceneViewportNavigation.md)
处理工具快捷键、look/pan 导航状态、输入捕获和 `SceneViewportInput` 构建。
- [SceneViewportChrome](SceneViewportChrome/SceneViewportChrome.md)
负责 Scene View 顶部 toolbar、左侧工具按钮 overlay以及工具切换命令折叠与执行。
- [SceneViewportEditorOverlayData](SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) - [SceneViewportEditorOverlayData](SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md)
定义 world line、sprite、screen triangle 与 handle record 组成的 canonical overlay 帧协议。 定义 world line、sprite、screen triangle 与 handle record 组成的 canonical overlay 帧协议。
- [SceneViewportOverlayProviders](SceneViewportOverlayProviders/SceneViewportOverlayProviders.md) - [SceneViewportOverlayProviders](SceneViewportOverlayProviders/SceneViewportOverlayProviders.md)
@@ -66,7 +74,7 @@
## 当前边界 ## 当前边界
- 这里是 editor 内部模块,不是 runtime public API。 - 这里是 editor 内部模块,不是 runtime public API。
- transform gizmo 的“形式化状态 -> overlay frame data -> hit-test / render”目前已经拆成多层 helper不应再按旧口径理解为某个单一 renderer 直接完成全部工作。 - transform gizmo 的“gizmo overlay state -> overlay frame data -> hit-test / render”目前已经拆成多层 helper不应再按旧口径理解为某个单一 renderer 直接完成全部工作。
## 相关文档 ## 相关文档
@@ -76,6 +84,7 @@
- [SceneViewportMath](SceneViewportMath/SceneViewportMath.md) - [SceneViewportMath](SceneViewportMath/SceneViewportMath.md)
- [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md) - [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md)
- [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md) - [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md)
- [SceneViewportChrome](SceneViewportChrome/SceneViewportChrome.md)
- [SceneViewportHudOverlay](SceneViewportHudOverlay/SceneViewportHudOverlay.md) - [SceneViewportHudOverlay](SceneViewportHudOverlay/SceneViewportHudOverlay.md)
- [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md) - [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md)
- [SceneViewportEditorOverlayData](SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md) - [SceneViewportEditorOverlayData](SceneViewportEditorOverlayData/SceneViewportEditorOverlayData.md)

View File

@@ -0,0 +1,38 @@
# BuildViewportRenderSurface
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
Rendering::RenderSurface BuildViewportRenderSurface(
uint32_t width,
uint32_t height,
RHI::RHIResourceView* colorView,
RHI::RHIResourceView* depthView,
RHI::ResourceStates colorStateBefore,
RHI::ResourceStates colorStateAfter = RHI::ResourceStates::PixelShaderResource);
```
## 作用
把颜色/深度资源视图和颜色状态转换信息打包成一个 `RenderSurface`
## 当前实现行为
- 会先创建 `Rendering::RenderSurface surface(width, height)`
- 然后依次设置:
- color attachment
- depth attachment
- color state before
- color state after
- 默认的 `colorStateAfter``PixelShaderResource`
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md)

View File

@@ -0,0 +1,37 @@
# BuildViewportTextureDesc
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
RHI::TextureDesc BuildViewportTextureDesc(
uint32_t width,
uint32_t height,
RHI::Format format);
```
## 作用
构造视口用的 2D 纹理描述。
## 当前实现行为
- 当前固定写入:
- `depth = 1`
- `mipLevels = 1`
- `arraySize = 1`
- `Texture2D`
- `sampleCount = 1`
- `sampleQuality = 0`
- `flags = 0`
- 只有宽度、高度和格式来自调用方。
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [BuildViewportTextureViewDesc](BuildViewportTextureViewDesc.md)

View File

@@ -0,0 +1,28 @@
# BuildViewportTextureViewDesc
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
RHI::ResourceViewDesc BuildViewportTextureViewDesc(RHI::Format format);
```
## 作用
构造视口纹理对应的 `Texture2D` 资源视图描述。
## 当前实现行为
- 当前只写入:
- `format`
- `dimension = Texture2D`
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [BuildViewportTextureDesc](BuildViewportTextureDesc.md)

View File

@@ -0,0 +1,34 @@
# CanReuseViewportResources
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
bool CanReuseViewportResources(const ViewportHostResourceReuseQuery& query);
```
## 作用
判断当前视口资源集合是否能直接复用到本帧,而不必重新创建。
## 当前实现行为
- 若请求宽高为 `0`,直接返回 `false`
- 若当前尺寸与请求尺寸不一致,也直接返回 `false`
- 颜色纹理、颜色 view、深度纹理、深度 view 和纹理描述符缺一不可。
- 若当前视口类型不要求 object-id 资源,则上述条件满足即可复用。
- 若要求 object-id 资源,则还必须同时具备:
- `hasObjectIdTexture`
- `hasObjectIdView`
- `hasObjectIdShaderView`
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [ViewportRequiresObjectIdResources](ViewportRequiresObjectIdResources.md)
- [ViewportHostResourceReuseQuery](ViewportHostResourceReuseQuery.md)

View File

@@ -0,0 +1,29 @@
# ClampViewportPixelCoordinate
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
uint32_t ClampViewportPixelCoordinate(float value, uint32_t extent);
```
## 作用
把浮点视口坐标稳定映射到纹理像素范围。
## 当前实现行为
-`extent == 0`,直接返回 `0`
- 否则会先把输入钳制到 `[0, extent - 1]`,再对结果取 `floor`
- 这样可以避免 GPU 像素读回越界。
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [ViewportObjectIdPicker](../ViewportObjectIdPicker/ViewportObjectIdPicker.md)
- [BuildViewportObjectIdReadbackRequest](../ViewportObjectIdPicker/BuildViewportObjectIdReadbackRequest.md)

View File

@@ -0,0 +1,32 @@
# ViewportHostResourcePresence
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 定义
```cpp
struct ViewportHostResourcePresence {
bool hasColorTexture = false;
bool hasColorView = false;
bool hasDepthTexture = false;
bool hasDepthView = false;
bool hasObjectIdTexture = false;
bool hasObjectIdView = false;
bool hasObjectIdShaderView = false;
bool hasTextureDescriptor = false;
};
```
## 作用
汇总一个视口 render target 集合当前是否具备关键颜色、深度和 object-id 资源。
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [ViewportHostResourceReuseQuery](ViewportHostResourceReuseQuery.md)
- [CanReuseViewportResources](CanReuseViewportResources.md)

View File

@@ -0,0 +1,41 @@
# ViewportHostResourceReuseQuery
**命名空间**: `XCEngine::Editor`
**类型**: `struct`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 定义
```cpp
struct ViewportHostResourceReuseQuery {
EditorViewportKind kind = EditorViewportKind::Scene;
uint32_t width = 0;
uint32_t height = 0;
uint32_t requestedWidth = 0;
uint32_t requestedHeight = 0;
ViewportHostResourcePresence resources = {};
};
```
## 作用
封装一次“当前视口资源是否还能直接复用”的判断输入。
## 字段说明
| 字段 | 说明 |
|------|------|
| `kind` | 视口类型。 |
| `width` | 当前资源宽度。 |
| `height` | 当前资源高度。 |
| `requestedWidth` | 本帧请求宽度。 |
| `requestedHeight` | 本帧请求高度。 |
| `resources` | 当前资源存在性摘要。 |
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [ViewportHostResourcePresence](ViewportHostResourcePresence.md)
- [CanReuseViewportResources](CanReuseViewportResources.md)

View File

@@ -0,0 +1,55 @@
# ViewportHostSurfaceUtils
**命名空间**: `XCEngine::Editor`
**类型**: `header-helper`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
**描述**: 提供视口资源重用判断、像素坐标钳制以及 `RenderSurface` 组装 helper。
## 概述
`ViewportHostSurfaceUtils.h``ViewportHostService` 的低层工具头。它解决的不是“怎么渲染场景”,而是“在把场景交给 renderer 之前,视口表面的元数据怎么判断和构造”。
## 公开类型与函数
| 成员 | 说明 |
|------|------|
| [ViewportHostResourcePresence](ViewportHostResourcePresence.md) | 汇总颜色、深度、object-id 和纹理描述符是否存在。 |
| [ViewportHostResourceReuseQuery](ViewportHostResourceReuseQuery.md) | 表达当前资源与本帧请求尺寸是否匹配。 |
| [ViewportRequiresObjectIdResources](ViewportRequiresObjectIdResources.md) | 当前仅 `Scene` 视口需要 object-id 资源。 |
| [ClampViewportPixelCoordinate](ClampViewportPixelCoordinate.md) | 把浮点鼠标坐标稳定映射到纹理像素范围。 |
| [CanReuseViewportResources](CanReuseViewportResources.md) | 判断是否可直接复用已有 render target。 |
| [BuildViewportTextureDesc](BuildViewportTextureDesc.md) | 生成 2D 纹理描述。 |
| [BuildViewportTextureViewDesc](BuildViewportTextureViewDesc.md) | 生成 texture view 描述。 |
| [BuildViewportRenderSurface](BuildViewportRenderSurface.md) | 把颜色/深度视图打包成 `RenderSurface`。 |
## 当前实现行为
- [CanReuseViewportResources](CanReuseViewportResources.md) 会严格检查宽高和必要资源存在性。
- `Scene` 视口如果缺 object-id 相关资源,就不会被判定为可复用。
- [ClampViewportPixelCoordinate](ClampViewportPixelCoordinate.md) 使用 `floor` 和范围钳制,保证读回像素不会越界。
## 设计说明
这层 helper 的意义在于把“资源是否还能继续用”与“真正如何渲染”分开。这样 `ViewportHostService` 的主流程就能更关注场景渲染和失败策略,而不是到处写尺寸比较和空指针判断。
## 当前限制
- 当前假定的是单样本 2D 纹理表面。
- 这里没有引入更复杂的 resize 策略,例如向上取整或池化复用。
## 相关文档
- [ViewportHostResourcePresence](ViewportHostResourcePresence.md)
- [ViewportHostResourceReuseQuery](ViewportHostResourceReuseQuery.md)
- [ViewportRequiresObjectIdResources](ViewportRequiresObjectIdResources.md)
- [ClampViewportPixelCoordinate](ClampViewportPixelCoordinate.md)
- [CanReuseViewportResources](CanReuseViewportResources.md)
- [BuildViewportTextureDesc](BuildViewportTextureDesc.md)
- [BuildViewportTextureViewDesc](BuildViewportTextureViewDesc.md)
- [BuildViewportRenderSurface](BuildViewportRenderSurface.md)
- [ViewportHostRenderTargets](../ViewportHostRenderTargets/ViewportHostRenderTargets.md)
- [ViewportHostService](../ViewportHostService/ViewportHostService.md)
- [ViewportObjectIdPicker](../ViewportObjectIdPicker/ViewportObjectIdPicker.md)

View File

@@ -0,0 +1,27 @@
# ViewportRequiresObjectIdResources
**命名空间**: `XCEngine::Editor`
**类型**: `function`
**源文件**: `editor/src/Viewport/ViewportHostSurfaceUtils.h`
## 签名
```cpp
bool ViewportRequiresObjectIdResources(EditorViewportKind kind);
```
## 作用
判断给定视口类型是否要求 object-id 相关资源。
## 当前实现行为
- 当前只有 `EditorViewportKind::Scene` 返回 `true`
- 其余视口类型都不要求 object-id 纹理、RTV 或 SRV。
## 相关文档
- [ViewportHostSurfaceUtils](ViewportHostSurfaceUtils.md)
- [CanReuseViewportResources](CanReuseViewportResources.md)