docs: add scene viewport interaction helper docs
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# BuildSceneViewportHudOverlayData
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
inline SceneViewportHudOverlayData BuildSceneViewportHudOverlayData(
|
||||
const SceneViewportOverlayData& sceneOverlay,
|
||||
bool showOrientationGizmo = true);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把一份 `SceneViewportOverlayData` 封装成 HUD overlay 输入。
|
||||
|
||||
## 当前行为
|
||||
|
||||
- 直接把 `sceneOverlay` 拷入结果
|
||||
- 把 `showOrientationGizmo` 写入结果
|
||||
|
||||
## 关键语义
|
||||
|
||||
- 这是一个头文件内联 helper,不做额外计算
|
||||
- `SceneViewPanel` 当前用它统一组装 hover 判定和最终绘制所需的 HUD 数据
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
`tests/Editor/test_scene_viewport_overlay_renderer.cpp` 的 `BuildSceneViewportHudOverlayDataTracksVisibilityIntent` 当前验证了默认可见和显式隐藏两条路径。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay.md)
|
||||
- [SceneViewportHudOverlayData](SceneViewportHudOverlayData.md)
|
||||
@@ -0,0 +1,37 @@
|
||||
# DrawSceneViewportHudOverlay
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
void DrawSceneViewportHudOverlay(
|
||||
ImDrawList* drawList,
|
||||
const SceneViewportHudOverlayData& overlay,
|
||||
const ImVec2& viewportMin,
|
||||
const ImVec2& viewportMax);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
在 Scene View 的 `ImDrawList` 上绘制前端 HUD overlay。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 当 `drawList == nullptr`、`overlay.HasVisibleElements() == false` 或 viewport 矩形无效时,直接返回
|
||||
- 否则先裁剪到当前 viewport 区域
|
||||
- 当前只会在 `showOrientationGizmo` 为真时调用 `DrawSceneViewportOrientationGizmo(...)`
|
||||
|
||||
## 关键语义
|
||||
|
||||
- 它当前不画 transform gizmo,也不画 scene icon
|
||||
- 这是一条纯前端 HUD 绘制链,不会把内容送进 GPU world overlay pass
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay.md)
|
||||
- [SceneViewportOrientationGizmo](../SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md)
|
||||
@@ -0,0 +1,39 @@
|
||||
# HitTestSceneViewportHudOverlay
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportHudOverlayHitResult HitTestSceneViewportHudOverlay(
|
||||
const SceneViewportHudOverlayData& overlay,
|
||||
const ImVec2& viewportMin,
|
||||
const ImVec2& viewportMax,
|
||||
const ImVec2& mousePosition);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把鼠标绝对位置解析成 HUD overlay 命中结果。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 当 HUD 不可见或 viewport 矩形无效时,返回空结果
|
||||
- 当前只会对 orientation gizmo 做命中测试
|
||||
- 命中成功时,返回:
|
||||
- `kind = SceneViewportHudOverlayHitKind::OrientationAxis`
|
||||
- `orientationAxis = 命中的具体轴`
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
`tests/Editor/test_scene_viewport_overlay_renderer.cpp` 的 `HitTestSceneViewportHudOverlaySkipsInvalidOrHiddenOverlay` 当前验证了无效和显式隐藏时会返回空结果。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay.md)
|
||||
- [SceneViewportHudOverlayHitResult](SceneViewportHudOverlayHitResult.md)
|
||||
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
@@ -0,0 +1,73 @@
|
||||
# SceneViewportHudOverlay
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `enum class + structs + free functions`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
**描述**: 定义 Scene View 前端 HUD overlay 的轻量数据结构、orientation gizmo 绘制入口以及对应的鼠标命中结果。
|
||||
|
||||
## 概览
|
||||
|
||||
`SceneViewportHudOverlay` 解决的是 Scene View 里“固定贴在 ImGui 前端的一层 HUD 交互”。
|
||||
|
||||
和 [SceneViewportEditorOverlayPass](../Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md) 的 GPU 世界 overlay 不同,这里处理的是:
|
||||
|
||||
- orientation gizmo 的可见性开关
|
||||
- orientation gizmo 的 ImGui draw-list 绘制
|
||||
- orientation gizmo 的鼠标命中
|
||||
|
||||
当前这层 HUD 不再承担 move / rotate / scale gizmo、scene icon 或 scene line 的主绘制链路;这些内容已经分别进入 editor overlay handle 命中链和 GPU overlay pass。
|
||||
|
||||
## 公开类型与函数
|
||||
|
||||
| 成员 | 说明 |
|
||||
|------|------|
|
||||
| `SceneViewportHudOverlayHitKind` | 当前 HUD 命中种类枚举。 |
|
||||
| [SceneViewportHudOverlayHitResult](SceneViewportHudOverlayHitResult.md) | HUD 命中结果;当前主要承载 orientation axis。 |
|
||||
| [SceneViewportHudOverlayData](SceneViewportHudOverlayData.md) | 一帧 HUD overlay 的输入数据。 |
|
||||
| [BuildSceneViewportHudOverlayData](BuildSceneViewportHudOverlayData.md) | 从 `SceneViewportOverlayData` 组装 HUD 数据。 |
|
||||
| [DrawSceneViewportHudOverlay](DrawSceneViewportHudOverlay.md) | 把 HUD 绘制到 `ImDrawList`。 |
|
||||
| [HitTestSceneViewportHudOverlay](HitTestSceneViewportHudOverlay.md) | 把鼠标位置解析成 HUD 命中结果。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
按 `SceneViewportHudOverlay.cpp` 的实现:
|
||||
|
||||
- HUD 只在 viewport 矩形有效时工作
|
||||
- 绘制时会先 `PushClipRect(viewportMin, viewportMax, true)`
|
||||
- 当前唯一的可见 HUD 元素是 orientation gizmo
|
||||
- 命中测试当前也只会返回 `OrientationAxis`
|
||||
|
||||
## 当前在 `SceneViewPanel` 中的使用方式
|
||||
|
||||
`SceneViewPanel` 当前会在两条链路里使用它:
|
||||
|
||||
- 交互判定阶段:
|
||||
- 先 `BuildSceneViewportHudOverlayData(overlay)`
|
||||
- 再交给 [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md) 参与命中合并
|
||||
- 最终绘制阶段:
|
||||
- 调用 [DrawSceneViewportHudOverlay](DrawSceneViewportHudOverlay.md)
|
||||
- 只补一层 ImGui HUD / orientation gizmo
|
||||
|
||||
## 与测试的对应关系
|
||||
|
||||
`tests/Editor/test_scene_viewport_overlay_renderer.cpp` 当前验证了:
|
||||
|
||||
- [BuildSceneViewportHudOverlayData](BuildSceneViewportHudOverlayData.md) 会正确追踪显示 / 隐藏意图。
|
||||
- [HitTestSceneViewportHudOverlay](HitTestSceneViewportHudOverlay.md) 会在 overlay 无效或 HUD 被隐藏时直接跳过命中。
|
||||
- 与 HUD 共用的 [ProjectSceneViewportWorldPoint](../SceneViewportMath/ProjectSceneViewportWorldPoint.md) 投影规则能把场景中心稳定映射到视口中心。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前 HUD 只有 orientation gizmo,没有 transform gizmo 或 scene icon
|
||||
- 命中结果只表达“点中了哪个朝向轴”,不直接执行相机对齐
|
||||
- 真正的相机对齐仍由 `ViewportHostService::AlignSceneViewToOrientationAxis(...)` 在更上层调用链中完成
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportOrientationGizmo](../SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md)
|
||||
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
- [SceneViewportEditorOverlayPass](../Passes/SceneViewportEditorOverlayPass/SceneViewportEditorOverlayPass.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
@@ -0,0 +1,25 @@
|
||||
# SceneViewportHudOverlayData
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `sceneOverlay` | `SceneViewportOverlayData` | orientation gizmo 绘制所需的相机/投影输入。 |
|
||||
| `showOrientationGizmo` | `bool` | 当前是否允许绘制和命中 orientation gizmo。 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- [HasVisibleElements](SceneViewportHudOverlay.md) 当前等价于:
|
||||
- `sceneOverlay.valid && showOrientationGizmo`
|
||||
- 因此这份数据既承载“相机姿态是否有效”,也承载“HUD 是否应该显示”
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay.md)
|
||||
- [BuildSceneViewportHudOverlayData](BuildSceneViewportHudOverlayData.md)
|
||||
@@ -0,0 +1,24 @@
|
||||
# SceneViewportHudOverlayHitResult
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportHudOverlay.h`
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `kind` | `SceneViewportHudOverlayHitKind` | 当前命中种类;默认是 `None`。 |
|
||||
| `orientationAxis` | `SceneViewportOrientationAxis` | 当命中 orientation gizmo 时记录具体轴向。 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- `HasHit()` 当前只检查 `kind != None`
|
||||
- 当前实现里,唯一有效的命中种类是 `OrientationAxis`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay.md)
|
||||
- [HitTestSceneViewportHudOverlay](HitTestSceneViewportHudOverlay.md)
|
||||
@@ -0,0 +1,41 @@
|
||||
# ApplySceneViewportHoveredHandleState
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
void ApplySceneViewportHoveredHandleState(
|
||||
const SceneViewportHoveredHandleState& hoveredHandleState,
|
||||
bool gizmoActive,
|
||||
bool showingMoveGizmo,
|
||||
SceneViewportMoveGizmo& moveGizmo,
|
||||
bool showingRotateGizmo,
|
||||
SceneViewportRotateGizmo& rotateGizmo,
|
||||
bool showingScaleGizmo,
|
||||
SceneViewportScaleGizmo& scaleGizmo);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把悬停状态写回当前显示中的各 gizmo。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 如果 `gizmoActive == true`,直接早退,不覆盖活动拖拽 gizmo 的句柄状态。
|
||||
- 否则按显示开关分别调用:
|
||||
- `moveGizmo.SetHoveredHandle(...)`
|
||||
- `rotateGizmo.SetHoveredHandle(...)`
|
||||
- `scaleGizmo.SetHoveredHandle(...)`
|
||||
|
||||
这保证命中解析层与 gizmo 自身 hover 表现之间只通过一份中间状态通信。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHoveredHandleState](SceneViewportHoveredHandleState.md)
|
||||
- [BuildSceneViewportHoveredHandleState](BuildSceneViewportHoveredHandleState.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
@@ -0,0 +1,34 @@
|
||||
# BuildSceneViewportHoveredHandleState
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportHoveredHandleState BuildSceneViewportHoveredHandleState(
|
||||
const SceneViewportInteractionResult& interaction);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
从统一命中结果中提取各 gizmo 需要的悬停句柄状态。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 先通过 `ToSceneViewportActiveGizmoKind(...)` 写入 `hoveredGizmoKind`。
|
||||
- 命中 `MoveGizmo` 时写入:
|
||||
- `moveAxis`
|
||||
- `movePlane`
|
||||
- 命中 `RotateGizmo` 时写入 `rotateAxis`。
|
||||
- 命中 `ScaleGizmo` 时写入 `scaleHandle`。
|
||||
- 其余命中类型返回空状态。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHoveredHandleState](SceneViewportHoveredHandleState.md)
|
||||
- [ApplySceneViewportHoveredHandleState](ApplySceneViewportHoveredHandleState.md)
|
||||
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
@@ -0,0 +1,57 @@
|
||||
# BuildSceneViewportInteractionActions
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportInteractionActions BuildSceneViewportInteractionActions(
|
||||
const SceneViewportInteractionResult& interaction,
|
||||
bool hasInteractiveViewport,
|
||||
bool clickedLeft,
|
||||
bool canResolveViewportInteraction);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把统一命中结果翻译成当前帧左键点击应该执行的动作集合。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
函数会先从 `interaction` 提取:
|
||||
|
||||
- `hoveredGizmoKind`
|
||||
- `orientationAxis`
|
||||
- `sceneIconEntityId`
|
||||
|
||||
随后按当前条件组合四个动作位:
|
||||
|
||||
- `beginTransformGizmo`
|
||||
- 需要 `hasInteractiveViewport`
|
||||
- 需要 `clickedLeft`
|
||||
- 需要命中的是 move / rotate / scale gizmo
|
||||
- `orientationGizmoClick`
|
||||
- 需要 `hasInteractiveViewport`
|
||||
- 需要 `clickedLeft`
|
||||
- 需要 `orientationAxis != None`
|
||||
- `sceneIconClick`
|
||||
- 需要 `hasInteractiveViewport`
|
||||
- 需要 `clickedLeft`
|
||||
- 需要 `sceneIconEntityId != 0`
|
||||
- `selectSceneClick`
|
||||
- 需要 `hasInteractiveViewport`
|
||||
- 需要 `clickedLeft`
|
||||
- 需要 `canResolveViewportInteraction`
|
||||
- 且 `interaction.HasHit() == false`
|
||||
|
||||
因此“空白区域点选场景”的兜底动作,只有在当前允许解析 viewport 交互且确实没有命中 overlay/HUD 时才会被置位。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionActions](SceneViewportInteractionActions.md)
|
||||
- [DispatchSceneViewportInteractionActions](DispatchSceneViewportInteractionActions.md)
|
||||
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
@@ -0,0 +1,68 @@
|
||||
# DispatchSceneViewportInteractionActions
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
void DispatchSceneViewportInteractionActions(
|
||||
const SceneViewportInteractionActions& actions,
|
||||
IEditorContext& context,
|
||||
IViewportHostService& viewportHostService,
|
||||
const ImVec2& viewportSize,
|
||||
const Math::Vector2& localMousePosition);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
执行不属于 gizmo 拖拽生命周期本身的点击副作用:朝向对齐、scene icon 直选与 object-id picking 兜底。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
### orientation gizmo 点击
|
||||
|
||||
若 `actions.orientationGizmoClick == true`,调用:
|
||||
|
||||
```cpp
|
||||
viewportHostService.AlignSceneViewToOrientationAxis(actions.orientationAxis);
|
||||
```
|
||||
|
||||
### scene icon 点击
|
||||
|
||||
若 `actions.sceneIconClick == true`,直接:
|
||||
|
||||
```cpp
|
||||
context.GetSelectionManager().SetSelectedEntity(actions.sceneIconEntityId);
|
||||
```
|
||||
|
||||
并立刻返回,不再执行 scene picking。
|
||||
|
||||
### 空白区域 scene picking
|
||||
|
||||
若 `actions.selectSceneClick == true`,调用:
|
||||
|
||||
```cpp
|
||||
viewportHostService.PickSceneViewEntity(
|
||||
context,
|
||||
viewportSize,
|
||||
ImVec2(localMousePosition.x, localMousePosition.y));
|
||||
```
|
||||
|
||||
- 命中实体时选择该实体
|
||||
- 未命中时清空选择
|
||||
|
||||
## 当前边界
|
||||
|
||||
- 该函数不处理 gizmo `TryBeginDrag(...)`;那部分仍由 `SceneViewPanel` 自己控制。
|
||||
- 它也不处理 look / pan 导航状态。
|
||||
- 它只分发点击后的副作用。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [BuildSceneViewportInteractionActions](BuildSceneViewportInteractionActions.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
- [IViewportHostService](../IViewportHostService/IViewportHostService.md)
|
||||
@@ -0,0 +1,29 @@
|
||||
# SceneViewportHoveredHandleState
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `hoveredGizmoKind` | `SceneViewportActiveGizmoKind` | 当前命中的 gizmo 大类。 |
|
||||
| `moveAxis` | `SceneViewportGizmoAxis` | move gizmo 轴命中。 |
|
||||
| `movePlane` | `SceneViewportGizmoPlane` | move gizmo 平面命中。 |
|
||||
| `rotateAxis` | `SceneViewportRotateGizmoAxis` | rotate gizmo 轴命中。 |
|
||||
| `scaleHandle` | `SceneViewportScaleGizmoHandle` | scale gizmo 句柄命中。 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- 这是面向 gizmo `SetHoveredHandle(...)` 的中间结构。
|
||||
- 同一时刻只会真正关心与 `hoveredGizmoKind` 对应的那一组字段。
|
||||
- 它不表达点击或选择副作用,只表达“当前鼠标悬停的是哪个 gizmo 句柄”。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionActions](SceneViewportInteractionActions.md)
|
||||
- [BuildSceneViewportHoveredHandleState](BuildSceneViewportHoveredHandleState.md)
|
||||
- [ApplySceneViewportHoveredHandleState](ApplySceneViewportHoveredHandleState.md)
|
||||
@@ -0,0 +1,68 @@
|
||||
# SceneViewportInteractionActions
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct + free functions`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
**描述**: 把 `SceneViewportInteractionResult` 翻译成 gizmo 悬停状态、点击语义与最终分发动作的辅助层。
|
||||
|
||||
## 概览
|
||||
|
||||
`SceneViewportInteractionActions` 是当前 Scene View 交互链路里“命中解析之后、真正执行动作之前”的收口层。
|
||||
|
||||
它解决三件事:
|
||||
|
||||
- 把统一命中结果映射成各 gizmo 可直接消费的悬停状态。
|
||||
- 把“这次左键点击到底意味着什么”收口成动作结构。
|
||||
- 把 orientation 对齐、scene icon 直选与 object-id picking 兜底从 `SceneViewPanel` 内联逻辑中抽出来。
|
||||
|
||||
当前 `SceneViewPanel` 仍然保留:
|
||||
|
||||
- 导航拖拽状态
|
||||
- gizmo drag begin / update / end 生命周期
|
||||
|
||||
但具体“点击语义如何解释”已经交给这层。
|
||||
|
||||
## `SceneViewportInteractionActions` 字段
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `hoveredGizmoKind` | 命中的 transform gizmo 大类。 |
|
||||
| `orientationAxis` | 命中 orientation gizmo 时的目标轴。 |
|
||||
| `sceneIconEntityId` | 命中 scene icon 时的实体 id。 |
|
||||
| `beginTransformGizmo` | 是否应该开始 gizmo 拖拽。 |
|
||||
| `orientationGizmoClick` | 是否应该执行视角对齐。 |
|
||||
| `sceneIconClick` | 是否应该直接选择 scene icon 对应实体。 |
|
||||
| `selectSceneClick` | 是否应该退回 object-id picking。 |
|
||||
|
||||
`HasClickAction()` 当前只检查四个点击布尔位中是否至少有一个为 `true`。
|
||||
|
||||
## 公开类型与函数
|
||||
|
||||
| 成员 | 说明 |
|
||||
|------|------|
|
||||
| [SceneViewportHoveredHandleState](SceneViewportHoveredHandleState.md) | 各 gizmo 可直接消费的悬停状态。 |
|
||||
| [ToSceneViewportActiveGizmoKind](ToSceneViewportActiveGizmoKind.md) | 把统一交互种类映射到 gizmo 大类。 |
|
||||
| [BuildSceneViewportHoveredHandleState](BuildSceneViewportHoveredHandleState.md) | 从统一命中结果提取悬停句柄。 |
|
||||
| [ApplySceneViewportHoveredHandleState](ApplySceneViewportHoveredHandleState.md) | 把悬停状态写回各 gizmo。 |
|
||||
| [BuildSceneViewportInteractionActions](BuildSceneViewportInteractionActions.md) | 把命中结果翻译成点击动作。 |
|
||||
| [DispatchSceneViewportInteractionActions](DispatchSceneViewportInteractionActions.md) | 执行 orientation 对齐、scene icon 直选与 scene picking 兜底。 |
|
||||
|
||||
## 测试锚点
|
||||
|
||||
`tests/Editor/test_scene_viewport_interaction_actions.cpp` 当前覆盖了:
|
||||
|
||||
- move 命中到 `SceneViewportHoveredHandleState` 的映射
|
||||
- orientation gizmo 点击动作生成
|
||||
- 空命中到 scene picking 兜底动作的生成
|
||||
- orientation 对齐动作分发
|
||||
- scene icon 点击分发
|
||||
- object-id picking 选择 / 清空选择分发
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionResolver](../SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
- [IViewportHostService](../IViewportHostService/IViewportHostService.md)
|
||||
@@ -0,0 +1,29 @@
|
||||
# ToSceneViewportActiveGizmoKind
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionActions.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportActiveGizmoKind ToSceneViewportActiveGizmoKind(SceneViewportInteractionKind kind);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把统一的 `SceneViewportInteractionKind` 映射成 gizmo 拖拽系统使用的 `SceneViewportActiveGizmoKind`。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `MoveGizmo` -> `SceneViewportActiveGizmoKind::Move`
|
||||
- `RotateGizmo` -> `SceneViewportActiveGizmoKind::Rotate`
|
||||
- `ScaleGizmo` -> `SceneViewportActiveGizmoKind::Scale`
|
||||
- `OrientationGizmo` / `SceneIcon` / `None` -> `SceneViewportActiveGizmoKind::None`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionActions](SceneViewportInteractionActions.md)
|
||||
- [BuildSceneViewportInteractionActions](BuildSceneViewportInteractionActions.md)
|
||||
@@ -0,0 +1,51 @@
|
||||
# ResolveSceneViewportInteraction
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function overloads`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionResolver.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportInteractionResult ResolveSceneViewportInteraction(
|
||||
const SceneViewportOverlayHandleHitResult& overlayHandleHit,
|
||||
const SceneViewportHudOverlayHitResult& hudOverlayHit);
|
||||
|
||||
SceneViewportInteractionResult ResolveSceneViewportInteraction(
|
||||
const SceneViewportInteractionResolveRequest& request);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把 Scene View 的多来源命中结果收敛成统一交互结果。
|
||||
|
||||
## 当前行为
|
||||
|
||||
### 直接合并重载
|
||||
|
||||
- 把 overlay handle 命中和 HUD 命中各自转成候选项
|
||||
- 依次比较 `priority`、`distanceSq`、`depth` 和 `secondaryPriority`
|
||||
- 返回当前最优候选对应的 [SceneViewportInteractionResult](SceneViewportInteractionResult.md)
|
||||
|
||||
### 请求式重载
|
||||
|
||||
- 如果 `overlayFrameData` 非空,先调用 `HitTestSceneViewportOverlayHandles(...)`
|
||||
- 如果 `hudOverlay` 非空,先调用 `HitTestSceneViewportHudOverlay(...)`
|
||||
- 再把两侧结果交给上面的直接合并重载
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
`tests/Editor/test_scene_viewport_interaction_resolver.cpp` 当前覆盖了:
|
||||
|
||||
- 两侧都空时返回 `None`
|
||||
- transform handle 会按优先级压过 HUD orientation 命中
|
||||
- HUD orientation 会压过 scene icon 命中
|
||||
- 请求式重载会正确委托到 overlay handle hit test
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionResolver](SceneViewportInteractionResolver.md)
|
||||
- [SceneViewportInteractionResolveRequest](SceneViewportInteractionResolveRequest.md)
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# SceneViewportInteractionResolveRequest
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionResolver.h`
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `overlayFrameData` | `const SceneViewportOverlayFrameData*` | world overlay / gizmo handle 命中输入。 |
|
||||
| `viewportSize` | `Math::Vector2` | 本地 viewport 尺寸。 |
|
||||
| `localMousePosition` | `Math::Vector2` | viewport 本地鼠标坐标。 |
|
||||
| `hudOverlay` | `const SceneViewportHudOverlayData*` | HUD overlay 命中输入。 |
|
||||
| `viewportMin` | `ImVec2` | viewport 左上角绝对坐标。 |
|
||||
| `viewportMax` | `ImVec2` | viewport 右下角绝对坐标。 |
|
||||
| `absoluteMousePosition` | `ImVec2` | 鼠标绝对坐标。 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- 这是一份“一次交互解析请求”的输入包
|
||||
- overlay handle 命中和 HUD 命中各自只消费自己需要的那部分字段
|
||||
- 某一侧输入为空时,解析器会把那一侧当作“无命中来源”
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionResolver](SceneViewportInteractionResolver.md)
|
||||
- [ResolveSceneViewportInteraction](ResolveSceneViewportInteraction.md)
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
@@ -0,0 +1,72 @@
|
||||
# SceneViewportInteractionResolver
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `enum class + structs + free functions`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionResolver.h`
|
||||
|
||||
**描述**: 把 Scene View 的 world overlay handle 命中结果和 HUD overlay 命中结果合并成统一交互结果。
|
||||
|
||||
## 概览
|
||||
|
||||
`SceneViewportInteractionResolver` 解决的是 Scene View 输入判定里的“最后一层归并”问题。
|
||||
|
||||
它的输入来自两条链路:
|
||||
|
||||
- [SceneViewportOverlayHitTester](../SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md)
|
||||
产出的 world overlay / gizmo handle 命中
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
产出的 orientation gizmo HUD 命中
|
||||
|
||||
它的输出是统一的 [SceneViewportInteractionResult](SceneViewportInteractionResult.md),供 `SceneViewPanel` 决定:
|
||||
|
||||
- 是不是开始 move / rotate / scale gizmo 拖拽
|
||||
- 是否执行 orientation gizmo 对齐
|
||||
- 是否把点击解释为 scene icon 命中
|
||||
|
||||
## 公开类型与函数
|
||||
|
||||
| 成员 | 说明 |
|
||||
|------|------|
|
||||
| `SceneViewportInteractionKind` | 统一交互种类枚举。 |
|
||||
| [SceneViewportInteractionResult](SceneViewportInteractionResult.md) | 统一交互结果。 |
|
||||
| [SceneViewportInteractionResolveRequest](SceneViewportInteractionResolveRequest.md) | 请求式重载的输入包。 |
|
||||
| [ResolveSceneViewportInteraction](ResolveSceneViewportInteraction.md) | 合并命中结果或从请求对象直接完成命中解析。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
按 `SceneViewportInteractionResolver.cpp` 的实现:
|
||||
|
||||
- 内部会把 HUD 命中和 overlay handle 命中都转成带优先级的候选项
|
||||
- 决策顺序依次比较:
|
||||
- `priority`
|
||||
- `distanceSq`
|
||||
- `depth`
|
||||
- `secondaryPriority`
|
||||
- HUD orientation gizmo 当前固定使用更高优先级
|
||||
- 请求式重载会先分别调用:
|
||||
- `HitTestSceneViewportOverlayHandles(...)`
|
||||
- `HitTestSceneViewportHudOverlay(...)`
|
||||
然后再复用同一套候选合并逻辑
|
||||
|
||||
## 与测试的对应关系
|
||||
|
||||
`tests/Editor/test_scene_viewport_interaction_resolver.cpp` 当前覆盖了:
|
||||
|
||||
- overlay 与 HUD 都为空时返回 `None`。
|
||||
- 高优先级 transform handle 会压过 HUD orientation 命中。
|
||||
- HUD orientation 会压过 scene icon 命中。
|
||||
- 请求式重载会走完整的 overlay handle hit-test 路径。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前只解决“命中了什么”,不执行后续动作
|
||||
- 它不持有任何交互状态,也不驱动拖拽生命周期
|
||||
- 具体拖拽开始/更新/结束仍由 `SceneViewPanel` 和各 gizmo 类处理
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
- [SceneViewportOverlayHitTester](../SceneViewportOverlayHitTester/SceneViewportOverlayHitTester.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
@@ -0,0 +1,30 @@
|
||||
# SceneViewportInteractionResult
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportInteractionResolver.h`
|
||||
|
||||
## 字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `kind` | `SceneViewportInteractionKind` | 当前统一交互种类。 |
|
||||
| `entityId` | `uint64_t` | scene icon 命中时的对象实体 ID。 |
|
||||
| `moveAxis` | `SceneViewportGizmoAxis` | move gizmo 轴命中。 |
|
||||
| `movePlane` | `SceneViewportGizmoPlane` | move gizmo 平面命中。 |
|
||||
| `rotateAxis` | `SceneViewportRotateGizmoAxis` | rotate gizmo 轴命中。 |
|
||||
| `scaleHandle` | `SceneViewportScaleGizmoHandle` | scale gizmo 句柄命中。 |
|
||||
| `orientationAxis` | `SceneViewportOrientationAxis` | orientation gizmo 轴命中。 |
|
||||
|
||||
## 当前语义
|
||||
|
||||
- `HasHit()` 当前只检查 `kind != None`
|
||||
- 各字段只在各自对应的 `kind` 下有效
|
||||
- 解析器不会帮调用方清理无关字段含义;调用方应按 `kind` 读取对应槽位
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportInteractionResolver](SceneViewportInteractionResolver.md)
|
||||
- [ResolveSceneViewportInteraction](ResolveSceneViewportInteraction.md)
|
||||
@@ -0,0 +1,39 @@
|
||||
# BuildSceneViewportAxisDragPlaneNormal
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool BuildSceneViewportAxisDragPlaneNormal(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const Math::Vector3& worldAxis,
|
||||
Math::Vector3& outPlaneNormal);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
为轴向拖拽推导一个尽量稳定、且不与活动轴平行的平面法线。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 若 overlay 无效或轴长度退化为零,则失败。
|
||||
- 会先把活动轴归一化。
|
||||
- 然后按如下顺序尝试候选法线:
|
||||
- 相机 `forward`
|
||||
- 相机 `up`
|
||||
- 相机 `right`
|
||||
- 世界 `up`
|
||||
- 世界 `right`
|
||||
- 世界 `forward`
|
||||
- 每个候选都会先投影到“去掉活动轴分量”的平面上;第一个非零结果会被归一化并返回。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [BuildSceneViewportPlaneFromPointNormal](BuildSceneViewportPlaneFromPointNormal.md)
|
||||
- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md)
|
||||
@@ -0,0 +1,29 @@
|
||||
# BuildSceneViewportPlaneFromPointNormal
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
Math::Plane BuildSceneViewportPlaneFromPointNormal(
|
||||
const Math::Vector3& point,
|
||||
const Math::Vector3& normal);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
根据一个点和法线构造拖拽或求交所需的平面。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 会先把法线归一化。
|
||||
- 然后使用 `Math::Plane(planeNormal, -Dot(planeNormal, point))` 构造结果。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [BuildSceneViewportAxisDragPlaneNormal](BuildSceneViewportAxisDragPlaneNormal.md)
|
||||
@@ -0,0 +1,31 @@
|
||||
# BuildSceneViewportProjectionMatrix
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
Math::Matrix4x4 BuildSceneViewportProjectionMatrix(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
float viewportWidth,
|
||||
float viewportHeight);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
根据垂直 FOV、视口尺寸和裁剪面构造透视投影矩阵。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 若 `viewportHeight <= 0`,当前会把纵横比回退到 `1.0f`。
|
||||
- 其余情况下按 `viewportWidth / viewportHeight` 计算 aspect。
|
||||
- 最终调用 `Math::Matrix4x4::Perspective(...)`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [BuildSceneViewportViewProjectionMatrix](BuildSceneViewportViewProjectionMatrix.md)
|
||||
@@ -0,0 +1,28 @@
|
||||
# BuildSceneViewportViewMatrix
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
Math::Matrix4x4 BuildSceneViewportViewMatrix(const SceneViewportOverlayData& overlay);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
根据当前 Scene View 相机姿态构造视图矩阵。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 会把 `cameraRight / cameraUp / cameraForward` 全部归一化。
|
||||
- 矩阵前三行分别使用右、上、前方向和相机位置的点积偏移组装。
|
||||
- 当前实现不额外检查 `overlay.valid`,默认由调用方保证输入有效。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [BuildSceneViewportViewProjectionMatrix](BuildSceneViewportViewProjectionMatrix.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# BuildSceneViewportViewProjectionMatrix
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
Math::Matrix4x4 BuildSceneViewportViewProjectionMatrix(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
float viewportWidth,
|
||||
float viewportHeight);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
组合视图矩阵与投影矩阵,得到用于世界点投影的 view-projection 矩阵。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 当前实现直接返回:
|
||||
- `Projection * View`
|
||||
- 它是 [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md) 和 [ProjectSceneViewportAxisDirectionAtPoint](ProjectSceneViewportAxisDirectionAtPoint.md) 的基础。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [BuildSceneViewportViewMatrix](BuildSceneViewportViewMatrix.md)
|
||||
- [BuildSceneViewportProjectionMatrix](BuildSceneViewportProjectionMatrix.md)
|
||||
@@ -0,0 +1,33 @@
|
||||
# DistanceToSegmentSquared
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
float DistanceToSegmentSquared(
|
||||
const Math::Vector2& point,
|
||||
const Math::Vector2& segmentStart,
|
||||
const Math::Vector2& segmentEnd,
|
||||
float* outSegmentT = nullptr);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
计算一个二维点到线段的平方距离。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 若线段长度退化到零,会直接退回“点到起点”的平方距离。
|
||||
- 否则会计算线段参数 `t`,并在 `[0, 1]` 内钳制。
|
||||
- 若传入了 `outSegmentT`,会回写最近点在线段上的参数位置。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md)
|
||||
- [SceneViewportRotateGizmo](../SceneViewportRotateGizmo/SceneViewportRotateGizmo.md)
|
||||
@@ -0,0 +1,32 @@
|
||||
# ProjectSceneViewportAxisDirection
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool ProjectSceneViewportAxisDirection(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const Math::Vector3& worldAxis,
|
||||
Math::Vector2& outScreenDirection);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
估计一个世界轴在当前视口屏幕上的二维方向。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 若 `overlay.valid == false`,直接失败。
|
||||
- 会先把 `worldAxis` 归一化并变换到当前视图空间。
|
||||
- 最终使用 `(viewAxis.x, -viewAxis.y)` 作为屏幕方向。
|
||||
- 若结果退化到零长度,则返回 `false`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [ProjectSceneViewportAxisDirectionAtPoint](ProjectSceneViewportAxisDirectionAtPoint.md)
|
||||
@@ -0,0 +1,35 @@
|
||||
# ProjectSceneViewportAxisDirectionAtPoint
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool ProjectSceneViewportAxisDirectionAtPoint(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
float viewportWidth,
|
||||
float viewportHeight,
|
||||
const Math::Vector3& worldPoint,
|
||||
const Math::Vector3& worldAxis,
|
||||
Math::Vector2& outScreenDirection,
|
||||
float sampleDistance = 1.0f);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
以具体世界采样点为基准,估计一个轴在屏幕上的方向。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 会先校验 overlay、视口尺寸、轴长度和 `sampleDistance`。
|
||||
- 主路径是投影 `worldPoint` 与 `worldPoint + axis * sampleDistance` 两个点,然后取它们的屏幕差向量。
|
||||
- 若任一点投影失败或结果退化到零长度,则回退到 [ProjectSceneViewportAxisDirection](ProjectSceneViewportAxisDirection.md)。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [ProjectSceneViewportAxisDirection](ProjectSceneViewportAxisDirection.md)
|
||||
@@ -0,0 +1,34 @@
|
||||
# ProjectSceneViewportWorldPoint
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportProjectedPoint ProjectSceneViewportWorldPoint(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
float viewportWidth,
|
||||
float viewportHeight,
|
||||
const Math::Vector3& worldPoint);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
把世界空间点投影到 Scene View 屏幕坐标。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 若 `overlay` 无效或视口宽高太小,会直接返回默认结果。
|
||||
- 会先计算 clip-space 点;`clipPoint.w <= epsilon` 时直接判定不可见。
|
||||
- 否则把点除以 `w` 转成 NDC,再换算到屏幕坐标。
|
||||
- `visible` 只有在 `x/y/z` 全部位于标准裁剪范围时才为真。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [SceneViewportProjectedPoint](SceneViewportProjectedPoint.md)
|
||||
- [ProjectSceneViewportWorldPointClamped](ProjectSceneViewportWorldPointClamped.md)
|
||||
@@ -0,0 +1,35 @@
|
||||
# ProjectSceneViewportWorldPointClamped
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
bool ProjectSceneViewportWorldPointClamped(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
float viewportWidth,
|
||||
float viewportHeight,
|
||||
const Math::Vector3& worldPoint,
|
||||
float edgePadding,
|
||||
SceneViewportProjectedPoint& outProjectedPoint);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
投影世界点,并把屏幕坐标钳制到给定边缘内。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 会先调用 [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md)。
|
||||
- 若 overlay 无效、视口尺寸无效或深度小于 `0`,则失败。
|
||||
- 否则按 `edgePadding` 把 `screenPosition` 钳制在视口矩形内部。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md)
|
||||
- [SceneViewportProjectedPoint](SceneViewportProjectedPoint.md)
|
||||
@@ -0,0 +1,84 @@
|
||||
# SceneViewportMath
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `header-helper`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
**描述**: 为 Scene View overlay、gizmo 和 picking 提供统一的投影、屏幕方向、拖拽平面和距离计算 helper。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneViewportMath.h` 是 `Viewport` 模块里最基础的“几何工具层”。它把很多本来容易散落在 gizmo / picker / overlay builder 里的数学过程集中到一个地方,例如:
|
||||
|
||||
- 构建 view / projection / view-projection 矩阵。
|
||||
- 世界点投影到视口屏幕坐标。
|
||||
- 世界轴投影到屏幕方向。
|
||||
- 线段距离计算。
|
||||
- 基于相机方向为轴向拖拽自动求稳定拖拽平面。
|
||||
|
||||
这类 helper 的价值很像商业引擎编辑器里的 `HandleUtility` 一类基础设施。
|
||||
|
||||
## 主要能力
|
||||
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| [SceneViewportProjectedPoint](SceneViewportProjectedPoint.md) | 世界点投影后的屏幕坐标、深度和可见性结果。 |
|
||||
| [BuildSceneViewportViewMatrix](BuildSceneViewportViewMatrix.md) | 由 `cameraRight / Up / Forward / Position` 组装视图矩阵。 |
|
||||
| [BuildSceneViewportProjectionMatrix](BuildSceneViewportProjectionMatrix.md) | 基于垂直 FOV 和视口宽高创建透视投影。 |
|
||||
| [BuildSceneViewportViewProjectionMatrix](BuildSceneViewportViewProjectionMatrix.md) | 组合视图矩阵与投影矩阵。 |
|
||||
| [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md) | 把世界点投影为屏幕坐标和 `ndcDepth`。 |
|
||||
| [ProjectSceneViewportAxisDirection](ProjectSceneViewportAxisDirection.md) | 计算世界轴在屏幕上的朝向。 |
|
||||
| [ProjectSceneViewportAxisDirectionAtPoint](ProjectSceneViewportAxisDirectionAtPoint.md) | 以具体采样点为基准估计屏幕轴方向。 |
|
||||
| [ProjectSceneViewportWorldPointClamped](ProjectSceneViewportWorldPointClamped.md) | 投影后做边缘钳制。 |
|
||||
| [DistanceToSegmentSquared](DistanceToSegmentSquared.md) | 供 gizmo hit-test 使用的二维距离 helper。 |
|
||||
| [BuildSceneViewportPlaneFromPointNormal](BuildSceneViewportPlaneFromPointNormal.md) | 由点和法线构建拖拽平面。 |
|
||||
| [BuildSceneViewportAxisDragPlaneNormal](BuildSceneViewportAxisDragPlaneNormal.md) | 为轴向拖拽推导合适的平面法线。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- 这些 helper 全部是 `inline` 函数,没有独立 `.cpp`。
|
||||
- [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md) 在 `clipPoint.w <= epsilon` 时会直接判定不可见。
|
||||
- [ProjectSceneViewportAxisDirectionAtPoint](ProjectSceneViewportAxisDirectionAtPoint.md) 会优先做两点投影采样,失败时回退到纯方向投影。
|
||||
- [BuildSceneViewportAxisDragPlaneNormal](BuildSceneViewportAxisDragPlaneNormal.md) 会按相机 forward / up / right 以及世界基轴顺序寻找一个不与拖拽轴平行的候选法线。
|
||||
|
||||
## 设计说明
|
||||
|
||||
把这些数学过程集中起来有两个收益:
|
||||
|
||||
- Scene View gizmo 的 hit-test、拖拽和绘制可以共享完全一致的投影逻辑。
|
||||
- 当视口投影规则调整时,不需要分别修改 move / rotate / scale 三套代码。
|
||||
|
||||
这类“统一几何约定层”是编辑器工具质量很重要的一部分。没有它,交互往往会出现看起来能点到、实际拖起来方向不对,或者不同 gizmo 手感不一致的问题。
|
||||
|
||||
## 与测试的对应关系
|
||||
|
||||
`tests/Editor/test_scene_viewport_overlay_renderer.cpp` 当前验证了:
|
||||
|
||||
- [BuildSceneViewportViewMatrix](BuildSceneViewportViewMatrix.md) 与编辑器相机 transform 约定一致。
|
||||
- [BuildSceneViewportProjectionMatrix](BuildSceneViewportProjectionMatrix.md) 和 [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md) 的投影结果符合 Scene View 预期。
|
||||
- [BuildSceneViewportAxisDragPlaneNormal](BuildSceneViewportAxisDragPlaneNormal.md) 会在相机 forward 与拖拽轴对齐时回退到其它稳定法线候选。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前投影 helper 假设的是标准透视视口语义,不是更一般化的任意裁剪空间工具库。
|
||||
- 没有对极端数值稳定性做更重的保护,例如非常接近 near plane 的大规模场景。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportProjectedPoint](SceneViewportProjectedPoint.md)
|
||||
- [BuildSceneViewportViewMatrix](BuildSceneViewportViewMatrix.md)
|
||||
- [BuildSceneViewportProjectionMatrix](BuildSceneViewportProjectionMatrix.md)
|
||||
- [BuildSceneViewportViewProjectionMatrix](BuildSceneViewportViewProjectionMatrix.md)
|
||||
- [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md)
|
||||
- [ProjectSceneViewportAxisDirection](ProjectSceneViewportAxisDirection.md)
|
||||
- [ProjectSceneViewportAxisDirectionAtPoint](ProjectSceneViewportAxisDirectionAtPoint.md)
|
||||
- [ProjectSceneViewportWorldPointClamped](ProjectSceneViewportWorldPointClamped.md)
|
||||
- [DistanceToSegmentSquared](DistanceToSegmentSquared.md)
|
||||
- [BuildSceneViewportPlaneFromPointNormal](BuildSceneViewportPlaneFromPointNormal.md)
|
||||
- [BuildSceneViewportAxisDragPlaneNormal](BuildSceneViewportAxisDragPlaneNormal.md)
|
||||
- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md)
|
||||
- [SceneViewportRotateGizmo](../SceneViewportRotateGizmo/SceneViewportRotateGizmo.md)
|
||||
- [SceneViewportScaleGizmo](../SceneViewportScaleGizmo/SceneViewportScaleGizmo.md)
|
||||
- [SceneViewportPicker](../SceneViewportPicker/SceneViewportPicker.md)
|
||||
@@ -0,0 +1,35 @@
|
||||
# SceneViewportProjectedPoint
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `struct`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportMath.h`
|
||||
|
||||
## 定义
|
||||
|
||||
```cpp
|
||||
struct SceneViewportProjectedPoint {
|
||||
Math::Vector2 screenPosition = Math::Vector2::Zero();
|
||||
float ndcDepth = 0.0f;
|
||||
bool visible = false;
|
||||
};
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
表示一个世界点投影到 Scene View 后的屏幕坐标、深度和可见性。
|
||||
|
||||
## 字段说明
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `screenPosition` | 投影后的屏幕坐标。 |
|
||||
| `ndcDepth` | 投影后的 NDC 深度。 |
|
||||
| `visible` | 是否位于可见裁剪范围内。 |
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportMath](SceneViewportMath.md)
|
||||
- [ProjectSceneViewportWorldPoint](ProjectSceneViewportWorldPoint.md)
|
||||
- [ProjectSceneViewportWorldPointClamped](ProjectSceneViewportWorldPointClamped.md)
|
||||
@@ -0,0 +1,38 @@
|
||||
# DrawSceneViewportOrientationGizmo
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportOrientationGizmo.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
void DrawSceneViewportOrientationGizmo(
|
||||
ImDrawList* drawList,
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const ImVec2& viewportMin,
|
||||
const ImVec2& viewportMax);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
在 Scene View 右上角绘制朝向 gizmo,包括中心立方体和六个方向轴帽。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `drawList == nullptr` 或 `overlay.valid == false` 时直接返回。
|
||||
- 会先根据 `viewportMin / viewportMax` 计算控件中心点。
|
||||
- 然后调用 `BuildSortedAxisHandles(overlay)` 生成六个方向 handle 的投影与排序数据。
|
||||
- 绘制顺序分为三段:
|
||||
- 先画 `sortDepth > 0` 的前景轴帽
|
||||
- 再画中心 cube
|
||||
- 最后画 `sortDepth <= 0` 的背面轴帽
|
||||
- 这种顺序让前向轴帽保持可见,同时仍然保留中心立方体对背向轴的遮挡关系。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo.md)
|
||||
- [HitTestSceneViewportOrientationGizmo](HitTestSceneViewportOrientationGizmo.md)
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
@@ -0,0 +1,43 @@
|
||||
# HitTestSceneViewportOrientationGizmo
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `function`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportOrientationGizmo.h`
|
||||
|
||||
## 签名
|
||||
|
||||
```cpp
|
||||
SceneViewportOrientationAxis HitTestSceneViewportOrientationGizmo(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const ImVec2& viewportMin,
|
||||
const ImVec2& viewportMax,
|
||||
const ImVec2& mousePosition);
|
||||
```
|
||||
|
||||
## 作用
|
||||
|
||||
检测鼠标当前命中了哪个朝向 gizmo handle,并返回对应的语义朝向轴。
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
- `overlay.valid == false` 时直接返回 `SceneViewportOrientationAxis::None`。
|
||||
- 会基于当前视口矩形重新计算控件中心。
|
||||
- 再构造一份 `AxisHandleVisual` 数组,并按 `sortDepth` 从小到大排序。
|
||||
- 随后依次调用 `HitTestAxisHandle(...)` 做命中测试,命中即返回:
|
||||
- `PositiveX / NegativeX`
|
||||
- `PositiveY / NegativeY`
|
||||
- `PositiveZ / NegativeZ`
|
||||
- 全部失败时返回 `SceneViewportOrientationAxis::None`。
|
||||
|
||||
## 设计含义
|
||||
|
||||
- 该函数只负责把 2D 点击解析成朝向语义。
|
||||
- 真正的相机对齐动作仍然由视口宿主服务执行。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo.md)
|
||||
- [DrawSceneViewportOrientationGizmo](DrawSceneViewportOrientationGizmo.md)
|
||||
- [ViewportHostService](../ViewportHostService/ViewportHostService.md)
|
||||
@@ -0,0 +1,55 @@
|
||||
# SceneViewportOrientationGizmo
|
||||
|
||||
**命名空间**: `XCEngine::Editor`
|
||||
|
||||
**类型**: `free functions`
|
||||
|
||||
**源文件**: `editor/src/Viewport/SceneViewportOrientationGizmo.h`
|
||||
|
||||
**描述**: 绘制 Scene View 右上角朝向 gizmo,并把鼠标点击解析为 `SceneViewportOrientationAxis`。
|
||||
|
||||
## 概述
|
||||
|
||||
`SceneViewportOrientationGizmo` 是 Scene View 里典型的“编辑器导航控件”。它不是变换 gizmo,也不直接修改相机,只负责两件事:
|
||||
|
||||
- 在右上角绘制一个朝向立方体和轴向帽。
|
||||
- 根据鼠标点击命中返回目标朝向轴。
|
||||
|
||||
真正的相机对齐动作仍然由 [IViewportHostService](../IViewportHostService/IViewportHostService.md) / [ViewportHostService](../ViewportHostService/ViewportHostService.md) 执行。
|
||||
|
||||
## 公开函数
|
||||
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| [DrawSceneViewportOrientationGizmo](DrawSceneViewportOrientationGizmo.md) | 绘制右上角朝向 gizmo。 |
|
||||
| [HitTestSceneViewportOrientationGizmo](HitTestSceneViewportOrientationGizmo.md) | 把鼠标位置解析为 `SceneViewportOrientationAxis`。 |
|
||||
|
||||
## 当前实现行为
|
||||
|
||||
按 `SceneViewportOrientationGizmo.cpp` 的实现:
|
||||
|
||||
- [DrawSceneViewportOrientationGizmo](DrawSceneViewportOrientationGizmo.md) 会把世界 `X / Y / Z` 轴转换到当前 Scene View 相机空间,并以自定义 cube + 轴向 cap 的方式绘制,而不是直接贴图。
|
||||
- [HitTestSceneViewportOrientationGizmo](HitTestSceneViewportOrientationGizmo.md) 会对轴向 handle 做独立命中测试,并返回 `PositiveX / NegativeX / ...` 这样的语义轴。
|
||||
|
||||
## 设计说明
|
||||
|
||||
这层分离很合理:
|
||||
|
||||
- UI helper 只关心“点中了哪个方向”。
|
||||
- 宿主服务再决定“如何让相机朝那个方向看过去”。
|
||||
|
||||
这样绘制与状态应用不会耦合在一个类里,后续如果要替换为更复杂的 orientation widget,也不需要重写视口宿主服务。
|
||||
|
||||
## 当前限制
|
||||
|
||||
- 当前返回的是轴语义,不包含自由旋转或拖拽环导航。
|
||||
- 控件交互是点击式,不是完整的 3D trackball。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [DrawSceneViewportOrientationGizmo](DrawSceneViewportOrientationGizmo.md)
|
||||
- [HitTestSceneViewportOrientationGizmo](HitTestSceneViewportOrientationGizmo.md)
|
||||
- [IViewportHostService](../IViewportHostService/IViewportHostService.md)
|
||||
- [ViewportHostService](../ViewportHostService/ViewportHostService.md)
|
||||
- [SceneViewportHudOverlay](../SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
@@ -21,12 +21,16 @@
|
||||
当前宿主实现,持有 editor camera、render target 与 Scene View overlay 缓存。
|
||||
- [SceneViewportCameraController](SceneViewportCameraController/SceneViewportCameraController.md)
|
||||
维护 Scene View 相机的焦点、距离、朝向和飞行速度,并把结果写回隐藏相机变换。
|
||||
- [SceneViewportMath](SceneViewportMath/SceneViewportMath.md)
|
||||
提供投影、屏幕方向、拖拽平面和距离计算等几何 helper,供 gizmo / overlay / picker 共用。
|
||||
- [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md)
|
||||
提供 CPU 射线选取 helper,当前更多用于辅助 gizmo 命中和保留的几何拾取路径。
|
||||
- [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md)
|
||||
封装 Scene View object-id 读回请求构建、像素坐标映射与颜色解码,是当前主点击选取链路的底层 helper。
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
负责前端 HUD / orientation gizmo 的构造、绘制和命中。
|
||||
- [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md)
|
||||
提供右上角朝向 gizmo 的绘制和点击命中,供 HUD overlay 复用。
|
||||
- [SceneViewportInteractionResolver](SceneViewportInteractionResolver/SceneViewportInteractionResolver.md)
|
||||
把 HUD 命中与 overlay handle 命中合并成统一交互结果。
|
||||
- [SceneViewportInteractionActions](SceneViewportInteractionActions/SceneViewportInteractionActions.md)
|
||||
@@ -55,6 +59,9 @@
|
||||
- [Editor](../Editor.md)
|
||||
- [SceneViewPanel](../panels/SceneViewPanel/SceneViewPanel.md)
|
||||
- [SceneViewportCameraController](SceneViewportCameraController/SceneViewportCameraController.md)
|
||||
- [SceneViewportMath](SceneViewportMath/SceneViewportMath.md)
|
||||
- [SceneViewportPicker](SceneViewportPicker/SceneViewportPicker.md)
|
||||
- [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md)
|
||||
- [SceneViewportHudOverlay](SceneViewportHudOverlay/SceneViewportHudOverlay.md)
|
||||
- [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md)
|
||||
- [SceneView Interaction And Gizmo Model](../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md)
|
||||
|
||||
Reference in New Issue
Block a user