From 038194b75a1cf0a27520f9aca0c0092ef242229a Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sat, 4 Apr 2026 13:32:31 +0800 Subject: [PATCH] docs: add scene viewport transform gizmo docs --- .../SceneViewportMoveGizmo/CancelDrag.md | 29 +++++ .../SceneViewportMoveGizmo/EndDrag.md | 30 +++++ .../SceneViewportMoveGizmo/EvaluateHit.md | 33 ++++++ .../SceneViewportGizmoAxis.md | 36 ++++++ .../SceneViewportGizmoPlane.md | 36 ++++++ .../SceneViewportMoveGizmo.md | 101 ++++++++++++++++ .../SceneViewportMoveGizmoContext.md | 33 ++++++ .../SceneViewportMoveGizmoDrawData.md | 36 ++++++ .../SceneViewportMoveGizmoHandleDrawData.md | 28 +++++ .../SceneViewportMoveGizmoHitResult.md | 30 +++++ .../SceneViewportMoveGizmoPlaneDrawData.md | 28 +++++ .../SetHoveredHandle.md | 30 +++++ .../SceneViewportMoveGizmo/StateQueries.md | 50 ++++++++ .../SceneViewportMoveGizmo/TryBeginDrag.md | 54 +++++++++ .../Viewport/SceneViewportMoveGizmo/Update.md | 37 ++++++ .../SceneViewportMoveGizmo/UpdateDrag.md | 42 +++++++ .../SceneViewportRotateGizmo/CancelDrag.md | 30 +++++ .../SceneViewportRotateGizmo/EndDrag.md | 30 +++++ .../SceneViewportRotateGizmo/EvaluateHit.md | 31 +++++ .../SceneViewportRotateGizmo.md | 111 ++++++++++++++++++ ...eneViewportRotateGizmoAngleFillDrawData.md | 28 +++++ .../SceneViewportRotateGizmoAxis.md | 38 ++++++ .../SceneViewportRotateGizmoContext.md | 35 ++++++ .../SceneViewportRotateGizmoDrawData.md | 33 ++++++ .../SceneViewportRotateGizmoHandleDrawData.md | 28 +++++ .../SceneViewportRotateGizmoHitResult.md | 28 +++++ ...SceneViewportRotateGizmoSegmentDrawData.md | 27 +++++ .../SetHoveredHandle.md | 29 +++++ .../SceneViewportRotateGizmo/StateQueries.md | 49 ++++++++ .../SceneViewportRotateGizmo/TryBeginDrag.md | 49 ++++++++ .../SceneViewportRotateGizmo/Update.md | 38 ++++++ .../SceneViewportRotateGizmo/UpdateDrag.md | 45 +++++++ .../SceneViewportScaleGizmo/CancelDrag.md | 29 +++++ .../SceneViewportScaleGizmo/EndDrag.md | 29 +++++ .../SceneViewportScaleGizmo/EvaluateHit.md | 34 ++++++ .../SceneViewportScaleGizmo.md | 107 +++++++++++++++++ ...eneViewportScaleGizmoAxisHandleDrawData.md | 30 +++++ ...eViewportScaleGizmoCenterHandleDrawData.md | 28 +++++ .../SceneViewportScaleGizmoContext.md | 33 ++++++ .../SceneViewportScaleGizmoDrawData.md | 32 +++++ .../SceneViewportScaleGizmoHandle.md | 38 ++++++ .../SceneViewportScaleGizmoHitResult.md | 28 +++++ .../SetHoveredHandle.md | 28 +++++ .../SceneViewportScaleGizmo/StateQueries.md | 49 ++++++++ .../SceneViewportScaleGizmo/TryBeginDrag.md | 48 ++++++++ .../SceneViewportScaleGizmo/Update.md | 33 ++++++ .../SceneViewportScaleGizmo/UpdateDrag.md | 42 +++++++ docs/api/XCEngine/Editor/Viewport/Viewport.md | 9 ++ 48 files changed, 1859 insertions(+) create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/CancelDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EndDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EvaluateHit.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoAxis.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoPlane.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmo.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoContext.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHandleDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHitResult.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoPlaneDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SetHoveredHandle.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/StateQueries.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/TryBeginDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/Update.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/UpdateDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/CancelDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EndDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EvaluateHit.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmo.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAngleFillDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAxis.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoContext.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHandleDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHitResult.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoSegmentDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SetHoveredHandle.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/StateQueries.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/TryBeginDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/Update.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/UpdateDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/CancelDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EndDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EvaluateHit.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmo.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoAxisHandleDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoCenterHandleDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoContext.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoDrawData.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHandle.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHitResult.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SetHoveredHandle.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/StateQueries.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/TryBeginDrag.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/Update.md create mode 100644 docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/UpdateDrag.md diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/CancelDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/CancelDrag.md new file mode 100644 index 00000000..007379be --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/CancelDrag.md @@ -0,0 +1,29 @@ +# SceneViewportMoveGizmo::CancelDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +void CancelDrag(IUndoManager* undoManager = nullptr); +``` + +## 作用 + +取消一次位移拖拽事务,并清理全部活动缓存。 + +## 当前实现行为 + +- 如果传入了 `undoManager` 且当前有 pending interactive change,会调用 `CancelInteractiveChange()` 回滚。 +- 同样会清空全部拖拽状态。 +- 额外会把 `hoveredAxis` 和 `hoveredPlane` 一并清空,避免取消后继续显示旧命中。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [EndDrag](EndDrag.md) +- [TryBeginDrag](TryBeginDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EndDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EndDrag.md new file mode 100644 index 00000000..09ebbb2c --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EndDrag.md @@ -0,0 +1,30 @@ +# SceneViewportMoveGizmo::EndDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +void EndDrag(IUndoManager& undoManager); +``` + +## 作用 + +提交一次位移拖拽事务,并清理全部活动缓存。 + +## 当前实现行为 + +- 当前没有活动拖拽时直接返回。 +- 若 `undoManager` 还持有 pending interactive change,会调用 `FinalizeInteractiveChange()` 提交位移结果。 +- 之后清空拖拽模式、活动轴/平面、活动实体 id、拖拽平面相关缓存以及对象起始位置数组。 +- 最后调用 `RefreshHandleState()` 去掉 active 标记。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [CancelDrag](CancelDrag.md) +- [UpdateDrag](UpdateDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EvaluateHit.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EvaluateHit.md new file mode 100644 index 00000000..3ab46ef5 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/EvaluateHit.md @@ -0,0 +1,33 @@ +# SceneViewportMoveGizmo::EvaluateHit + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +SceneViewportMoveGizmoHitResult EvaluateHit(const Math::Vector2& mousePosition) const; +``` + +## 作用 + +执行位移 gizmo 的命中检测,并返回当前最近命中的轴向或平面 handle。 + +## 当前实现行为 + +- draw data 不可见时直接返回空命中。 +- 会先遍历三条轴向 handle,用鼠标到线段的距离平方做最近点比较。 +- 只有当轴向命中失败时,才会继续测试 `XY / XZ / YZ` 三个平面拖拽块。 +- 平面命中通过 `PointInQuad(...)` 判断,并按四边形中心到鼠标的距离选最近平面。 +- 因此当前优先级是: + - 轴向 handle + - 再到平面 handle + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SetHoveredHandle](SetHoveredHandle.md) +- [SceneViewportMoveGizmoHitResult](SceneViewportMoveGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoAxis.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoAxis.md new file mode 100644 index 00000000..3d1dc8f0 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoAxis.md @@ -0,0 +1,36 @@ +# SceneViewportGizmoAxis + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 定义 + +```cpp +enum class SceneViewportGizmoAxis : uint8_t { + None = 0, + X, + Y, + Z +}; +``` + +## 作用 + +表示当前 move gizmo 选中的单轴拖拽方向。 + +## 枚举值 + +| 值 | 说明 | +|------|------| +| `None` | 没有命中或没有激活单轴。 | +| `X` | 世界或局部 gizmo 的 X 轴。 | +| `Y` | 世界或局部 gizmo 的 Y 轴。 | +| `Z` | 世界或局部 gizmo 的 Z 轴。 | + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoHitResult](SceneViewportMoveGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoPlane.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoPlane.md new file mode 100644 index 00000000..a1d172b5 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportGizmoPlane.md @@ -0,0 +1,36 @@ +# SceneViewportGizmoPlane + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 定义 + +```cpp +enum class SceneViewportGizmoPlane : uint8_t { + None = 0, + XY, + XZ, + YZ +}; +``` + +## 作用 + +表示当前 move gizmo 选中的平面拖拽约束。 + +## 枚举值 + +| 值 | 说明 | +|------|------| +| `None` | 没有命中或没有激活平面 handle。 | +| `XY` | 在 `XY` 平面内移动。 | +| `XZ` | 在 `XZ` 平面内移动。 | +| `YZ` | 在 `YZ` 平面内移动。 | + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoHitResult](SceneViewportMoveGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmo.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmo.md new file mode 100644 index 00000000..0015d5f0 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmo.md @@ -0,0 +1,101 @@ +# SceneViewportMoveGizmo + +**命名空间**: `XCEngine::Editor` + +**类型**: `class + enums + structs` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +**描述**: Scene View 位移 gizmo,负责轴向/平面拖拽命中、可视化数据生成和交互式撤销集成。 + +## 概述 + +`SceneViewportMoveGizmo` 是当前 Scene View 三套 transform gizmo 中最直接的一套。它围绕一个选中 pivot 工作,并支持两类拖拽: + +- 单轴拖拽: `X / Y / Z` +- 平面拖拽: `XY / XZ / YZ` + +除了当前主选对象,它还会携带 `selectedObjects`,因此多选平移是当前真实支持的能力。 + +## 公开类型 + +| 成员 | 说明 | +|------|------| +| [SceneViewportGizmoAxis](SceneViewportGizmoAxis.md) | `X / Y / Z` 轴枚举。 | +| [SceneViewportGizmoPlane](SceneViewportGizmoPlane.md) | `XY / XZ / YZ` 平面枚举。 | +| [SceneViewportMoveGizmoHandleDrawData](SceneViewportMoveGizmoHandleDrawData.md) | 单个轴向 handle 的绘制状态。 | +| [SceneViewportMoveGizmoPlaneDrawData](SceneViewportMoveGizmoPlaneDrawData.md) | 单个平面 handle 的绘制状态。 | +| [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) | 当前帧完整 gizmo 绘制数据。 | +| [SceneViewportMoveGizmoContext](SceneViewportMoveGizmoContext.md) | update / drag 所需上下文,包括 overlay、鼠标位置、pivot 和选中对象集合。 | +| [SceneViewportMoveGizmoHitResult](SceneViewportMoveGizmoHitResult.md) | 命中结果。 | + +## 公开 API + +### 交互主流程 + +- [Update](Update.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) + +### 状态查询 + +- [State Queries](StateQueries.md) + +## 当前实现行为 + +按 `SceneViewportMoveGizmo.cpp` 的实现: + +- `TryBeginDrag(...)` 会先从鼠标位置构建世界射线。 +- 轴向拖拽会用 [BuildSceneViewportAxisDragPlaneNormal](../SceneViewportMath/SceneViewportMath.md) 计算一个稳定拖拽平面。 +- 平面拖拽直接使用所选平面的法线。 +- 拖拽开始时会调用 `undoManager.BeginInteractiveChange("Move Gizmo")`。 +- 多选情况下,会记录每个对象的初始世界坐标,然后统一叠加同一个 `worldDelta`。 +- 轴向拖拽通过“射线与拖拽平面求交 -> 投影到活动轴 -> 比较标量差值”得到位移。 +- 平面拖拽通过“当前命中点 - 起始命中点”再投影到活动平面得到位移。 + +## 设计说明 + +Move gizmo 的关键不是把对象“随鼠标走”,而是把 2D 鼠标输入稳定映射成 3D 约束位移。当前实现采用“拖拽平面 + 轴投影”的方式,是编辑器里很成熟的做法,因为它能兼顾: + +- 轴向操作的稳定性。 +- 平面操作的直观性。 +- 与相机视角变化的兼容性。 + +## 生命周期与线程语义 + +- gizmo 对象由 [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) 作为成员持有。 +- [Update](Update.md) 负责刷新绘制数据与 hover 状态。 +- [TryBeginDrag](TryBeginDrag.md) / [UpdateDrag](UpdateDrag.md) / [EndDrag](EndDrag.md) / [CancelDrag](CancelDrag.md) 构成一次交互式事务。 + +## 与测试的对应关系 + +`tests/Editor/test_scene_viewport_move_gizmo.cpp` 当前覆盖了: + +- `X` 轴 handle 的悬停命中。 +- 轴向拖拽只改动对应世界轴,并能生成 / 回滚交互式撤销。 +- 轴几乎正对相机时会缩短而不是保持满长度。 +- 等轴视角下平面 handle 可见且可命中。 +- `XY` 平面拖拽会改动 `X / Y` 但保持 `Z` 不变。 + +## 当前限制 + +- 当前只做平移,不处理吸附、栅格对齐或轴锁定增量显示。 +- 拖拽基于当前世界位置直接写回 transform,没有额外的坐标系可视化历史。 + +## 相关文档 + +- [SceneViewportGizmoAxis](SceneViewportGizmoAxis.md) +- [SceneViewportGizmoPlane](SceneViewportGizmoPlane.md) +- [SceneViewportMoveGizmoContext](SceneViewportMoveGizmoContext.md) +- [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) +- [SceneViewportMoveGizmoHitResult](SceneViewportMoveGizmoHitResult.md) +- [State Queries](StateQueries.md) +- [SceneViewportMath](../SceneViewportMath/SceneViewportMath.md) +- [SceneViewportRotateGizmo](../SceneViewportRotateGizmo/SceneViewportRotateGizmo.md) +- [SceneViewportScaleGizmo](../SceneViewportScaleGizmo/SceneViewportScaleGizmo.md) +- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) +- [SceneView Interaction And Gizmo Model](../../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoContext.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoContext.md new file mode 100644 index 00000000..5e991b25 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoContext.md @@ -0,0 +1,33 @@ +# SceneViewportMoveGizmoContext + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 作用 + +封装 move gizmo 在 update、hit-test 和拖拽阶段所需的输入上下文。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `overlay` | 当前 Scene View 相机 overlay 数据。 | +| `viewportSize` | 视口尺寸。 | +| `mousePosition` | 视口内鼠标位置。 | +| `selectedObject` | 当前主选对象。 | +| `selectedObjects` | 当前全部选中对象,用于多选平移。 | +| `pivotWorldPosition` | gizmo pivot 的世界坐标。 | +| `axisOrientation` | gizmo 轴向所使用的旋转基。 | + +## 当前使用方式 + +- `Update(...)` 使用它构建 draw data 和 hover 状态。 +- `TryBeginDrag(...)` / `UpdateDrag(...)` 使用它从鼠标位置构建世界射线并计算拖拽位移。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoDrawData.md new file mode 100644 index 00000000..d6d1c1a6 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoDrawData.md @@ -0,0 +1,36 @@ +# SceneViewportMoveGizmoDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 作用 + +封装当前帧 move gizmo 的完整绘制数据,供 gizmo overlay state 构建与 editor overlay frame data 复用。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `visible` | 整个 move gizmo 当前是否可见。 | +| `pivot` | gizmo pivot 的屏幕空间位置。 | +| `pivotRadius` | pivot 圆点半径。 | +| `handles` | 三个轴向 handle 的绘制数据。 | +| `planes` | 三个平面 handle 的绘制数据。 | + +## 当前使用方式 + +- `SceneViewportMoveGizmo::Update(...)` 会刷新这份数据。 +- `SceneViewPanel` 会经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它与当前实体 id 聚合成 overlay submission。 +- [SceneViewportOverlayProviders](../SceneViewportOverlayProviders/SceneViewportOverlayProviders.md) 中的 transform-gizmo provider 会把它转成: + - `handleRecords` + - `screenTriangles` + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoHandleDrawData](SceneViewportMoveGizmoHandleDrawData.md) +- [SceneViewportMoveGizmoPlaneDrawData](SceneViewportMoveGizmoPlaneDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHandleDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHandleDrawData.md new file mode 100644 index 00000000..62f6ffc7 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHandleDrawData.md @@ -0,0 +1,28 @@ +# SceneViewportMoveGizmoHandleDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 作用 + +描述单个轴向 move handle 在当前帧的 2D 绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `axis` | 该 handle 对应的轴。 | +| `start` | 屏幕空间起点。 | +| `end` | 屏幕空间终点。 | +| `color` | 线段与箭头主色。 | +| `visible` | 当前帧是否应该绘制。 | +| `hovered` | 鼠标是否悬停在该 handle 上。 | +| `active` | 当前是否正在拖拽该 handle。 | + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHitResult.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHitResult.md new file mode 100644 index 00000000..4c6f372f --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoHitResult.md @@ -0,0 +1,30 @@ +# SceneViewportMoveGizmoHitResult + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 作用 + +表示一次 move gizmo hit-test 的结果。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `axis` | 命中的单轴 handle;未命中时为 `None`。 | +| `plane` | 命中的平面 handle;未命中时为 `None`。 | +| `distanceSq` | 命中点到鼠标的平方距离,用于最近命中比较。 | + +## 当前实现行为 + +- 内联函数 `HasHit()` 只要 `axis` 或 `plane` 任一非 `None` 就返回 `true`。 +- 当前设计允许调用方统一处理“单轴命中”和“平面命中”两种情况。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportGizmoAxis](SceneViewportGizmoAxis.md) +- [SceneViewportGizmoPlane](SceneViewportGizmoPlane.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoPlaneDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoPlaneDrawData.md new file mode 100644 index 00000000..8a4eeda8 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SceneViewportMoveGizmoPlaneDrawData.md @@ -0,0 +1,28 @@ +# SceneViewportMoveGizmoPlaneDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 作用 + +描述单个平面 move handle 在当前帧的 2D 绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `plane` | 该 handle 对应的平面约束。 | +| `corners` | 平面四边形在屏幕空间的四个角点。 | +| `fillColor` | 平面填充色。 | +| `outlineColor` | 平面轮廓色。 | +| `visible` | 当前帧是否应该绘制。 | +| `hovered` | 鼠标是否悬停在该平面上。 | +| `active` | 当前是否正在拖拽该平面。 | + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SetHoveredHandle.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SetHoveredHandle.md new file mode 100644 index 00000000..ac1e7ba7 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/SetHoveredHandle.md @@ -0,0 +1,30 @@ +# SceneViewportMoveGizmo::SetHoveredHandle + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +void SetHoveredHandle(SceneViewportGizmoAxis axis, SceneViewportGizmoPlane plane); +``` + +## 作用 + +允许外层交互系统直接写入当前 hover 结果。 + +## 当前实现行为 + +- 当前存在活动拖拽时不会覆盖内部状态。 +- 若传入了有效轴,会强制清空平面 hover。 +- 若轴为 `None`,则保留传入的平面 hover。 +- 写入后会通过 `RefreshHandleState()` 同步显示状态。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [EvaluateHit](EvaluateHit.md) +- [Update](Update.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/StateQueries.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/StateQueries.md new file mode 100644 index 00000000..14779534 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/StateQueries.md @@ -0,0 +1,50 @@ +# SceneViewportMoveGizmo::State Queries + +**命名空间**: `XCEngine::Editor` + +**类型**: `methods` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +bool IsHoveringHandle() const; +bool IsActive() const; +uint64_t GetActiveEntityId() const; +const SceneViewportMoveGizmoDrawData& GetDrawData() const; +``` + +## 作用 + +提供 move gizmo 当前 hover / active 状态、活动实体以及每帧 draw data 的只读访问。 + +## 当前实现行为 + +### `IsHoveringHandle()` + +- 只要 `m_hoveredAxis != None` 或 `m_hoveredPlane != None` 就返回 `true`。 +- 因此它同时覆盖“轴 handle 悬停”和“平面 handle 悬停”。 + +### `IsActive()` + +- 只要 `m_activeAxis != None` 或 `m_activePlane != None` 就返回 `true`。 +- 表达的是“当前是否正在执行拖拽事务”,不是“gizmo 是否可见”。 + +### `GetActiveEntityId()` + +- 直接返回 `m_activeEntityId`。 +- 未进入拖拽时通常为 `0`。 + +### `GetDrawData()` + +- 返回 `m_drawData` 的常量引用。 +- 该数据由 [Update](Update.md) 与内部 `BuildDrawData(...)` / `RefreshHandleState()` 维护。 +- 当前主调用链不会让 HUD 直接读取它;`SceneViewPanel` 会先经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它聚合进 overlay submission,最终由 provider 体系转成 canonical `screenTriangles` 与 `handleRecords`。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [Update](Update.md) +- [SceneViewportMoveGizmoDrawData](SceneViewportMoveGizmoDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/TryBeginDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/TryBeginDrag.md new file mode 100644 index 00000000..7c0da5ec --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/TryBeginDrag.md @@ -0,0 +1,54 @@ +# SceneViewportMoveGizmo::TryBeginDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +bool TryBeginDrag(const SceneViewportMoveGizmoContext& context, IUndoManager& undoManager); +``` + +## 作用 + +在当前 hover 的轴或平面上启动位移拖拽,并准备 interactive undo 所需的起始数据。 + +## 当前实现行为 + +- 只会在以下条件满足时进入拖拽: + - 当前没有活动拖拽 + - 当前命中了轴或平面 handle + - `selectedObject` 有效 + - draw data 可见 + - `undoManager` 当前没有 pending interactive change +- 会先根据 `overlay + viewportSize + mousePosition` 构建世界射线。 +- 轴向拖拽路径: + - 通过 `GetAxisVector(...)` 得到当前世界轴 + - 调用 `BuildSceneViewportAxisDragPlaneNormal(...)` 构造稳定拖拽平面法线 +- 平面拖拽路径: + - 直接从当前命中平面得到世界法线 +- 之后统一构造 `dragPlane`,并计算起始命中点 `hitPoint`。 +- 成功后调用 `undoManager.BeginInteractiveChange("Move Gizmo")`。 +- 缓存的状态包括: + - 当前拖拽模式 `Axis / Plane` + - 活动轴或活动平面 + - 活动实体 id + - 活动世界轴或平面法线 + - 起始 pivot、起始命中点、起始轴标量 + - 所有参与拖拽对象的起始世界位置 +- 如果 `selectedObjects` 为空,会退回到单对象拖拽。 + +## 返回值 + +- `true`: 已成功切换到拖拽状态。 +- `false`: 几何求解、命中条件或 interactive undo 任一环节失败。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/Update.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/Update.md new file mode 100644 index 00000000..a7c0f3c5 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/Update.md @@ -0,0 +1,37 @@ +# SceneViewportMoveGizmo::Update + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +void Update(const SceneViewportMoveGizmoContext& context); +``` + +## 作用 + +刷新当前帧位移 gizmo 的绘制数据,并维护轴向或平面 handle 的 hover 状态。 + +## 当前实现行为 + +- 会先调用 `BuildDrawData(context)` 生成轴向箭头与平面拖拽块的当前帧绘制数据。 +- 当前没有活动拖拽且鼠标位于视口内时,会调用 `EvaluateHit(context.mousePosition)` 自动命中: + - 最近的轴向线段 + - 或可见平面四边形 +- 当前没有活动拖拽但鼠标已离开视口时,会清空 `hoveredAxis` 与 `hoveredPlane`。 +- 当前正在拖拽时: + - 轴向拖拽会把 hover 轴锁定到活动轴 + - 平面拖拽会把 hover 平面锁定到活动平面 +- 末尾通过 `RefreshHandleState()` 同步 draw data 中的 hovered / active 标记。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/UpdateDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/UpdateDrag.md new file mode 100644 index 00000000..5593aa13 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportMoveGizmo/UpdateDrag.md @@ -0,0 +1,42 @@ +# SceneViewportMoveGizmo::UpdateDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportMoveGizmo.h` + +## 签名 + +```cpp +void UpdateDrag(const SceneViewportMoveGizmoContext& context); +``` + +## 作用 + +根据当前鼠标射线与缓存拖拽平面的交点,持续更新对象位移。 + +## 当前实现行为 + +- 只有在活动拖拽仍然有效、主选对象 id 未变化、缓存对象数组与起始位置数组长度一致时才会继续。 +- 每一帧都会重新从视口状态构建世界射线,并与缓存的 `m_dragPlane` 求交。 +- 轴向拖拽: + - 计算当前命中点相对起始 pivot 在活动轴上的投影标量 + - 用当前标量减去 `m_dragStartAxisScalar` 得到 `deltaScalar` + - 最终位移为 `m_activeAxisDirection * deltaScalar` +- 平面拖拽: + - 计算 `hitPoint - m_dragStartHitWorldPosition` + - 再通过 `ProjectOnPlane(..., m_activePlaneNormal)` 去掉法线方向分量 +- 对所有参与拖拽对象都会叠加同一个 `worldDelta`,实现多选统一平移。 + +## 当前实现边界 + +- 拖拽过程中不会重新选择对象。 +- 当前没有吸附、网格对齐或数值输入。 + +## 相关文档 + +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/CancelDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/CancelDrag.md new file mode 100644 index 00000000..b5261380 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/CancelDrag.md @@ -0,0 +1,30 @@ +# SceneViewportRotateGizmo::CancelDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +void CancelDrag(IUndoManager* undoManager = nullptr); +``` + +## 作用 + +取消一次旋转拖拽事务,并清理全部活动状态。 + +## 当前实现行为 + +- 允许传入空指针。 +- 如果传入了 `undoManager` 且当前存在 pending interactive change,会调用 `CancelInteractiveChange()` 回滚本次事务。 +- 与 [EndDrag](EndDrag.md) 一样会清空全部活动状态。 +- 额外会把 `hoveredAxis` 也清回 `None`,避免取消后继续显示旧 hover。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [EndDrag](EndDrag.md) +- [TryBeginDrag](TryBeginDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EndDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EndDrag.md new file mode 100644 index 00000000..551cfed5 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EndDrag.md @@ -0,0 +1,30 @@ +# SceneViewportRotateGizmo::EndDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +void EndDrag(IUndoManager& undoManager); +``` + +## 作用 + +结束一次旋转拖拽事务,并提交交互式撤销结果。 + +## 当前实现行为 + +- 若当前没有活动轴,直接返回。 +- 当 `undoManager` 仍持有 pending interactive change 时,会调用 `FinalizeInteractiveChange()` 提交本次旋转。 +- 随后清空活动轴、活动实体、拖拽平面、起始角、共享 pivot 标志和所有缓存对象姿态。 +- 会保留当前 hover 刷新逻辑,并通过 `RefreshHandleState()` 去掉 active 标记。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [CancelDrag](CancelDrag.md) +- [UpdateDrag](UpdateDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EvaluateHit.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EvaluateHit.md new file mode 100644 index 00000000..c4474544 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/EvaluateHit.md @@ -0,0 +1,31 @@ +# SceneViewportRotateGizmo::EvaluateHit + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +SceneViewportRotateGizmoHitResult EvaluateHit(const Math::Vector2& mousePosition) const; +``` + +## 作用 + +提供旋转环命中检测,并返回当前最近命中的轴。 + +## 当前实现行为 + +- 如果当前 draw data 不可见,直接返回空命中。 +- 会遍历每个可见 handle 的所有离散线段。 +- 对普通 `X / Y / Z` 环,只考虑 `frontFacing = true` 的可见线段。 +- `View` 环不受前后向裁剪限制。 +- 使用固定像素阈值比较鼠标到线段的距离平方,并返回最近命中的轴。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SetHoveredHandle](SetHoveredHandle.md) +- [SceneViewportRotateGizmoHitResult](SceneViewportRotateGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmo.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmo.md new file mode 100644 index 00000000..299f3fb1 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmo.md @@ -0,0 +1,111 @@ +# SceneViewportRotateGizmo + +**命名空间**: `XCEngine::Editor` + +**类型**: `class + enum + structs` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +**描述**: Scene View 旋转 gizmo,支持轴向环、视图环、多对象旋转、共享 pivot 旋转以及交互式撤销。 + +## 概述 + +`SceneViewportRotateGizmo` 是当前三套 transform gizmo 里几何与交互最复杂的一套。它支持四种 handle: + +- `X` +- `Y` +- `Z` +- `View` + +同时它还能配合: + +- local / global 空间模式 +- `Pivot / Center` 模式 +- 多选对象旋转 + +## 公开 API + +### 交互主流程 + +- [Update](Update.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) + +### 状态查询 + +- [State Queries](StateQueries.md) + +### 公开类型 + +| 类型 | 说明 | +|------|------| +| [SceneViewportRotateGizmoAxis](SceneViewportRotateGizmoAxis.md) | 旋转 gizmo 的 handle 轴枚举。 | +| [SceneViewportRotateGizmoSegmentDrawData](SceneViewportRotateGizmoSegmentDrawData.md) | 单个环段的绘制数据。 | +| [SceneViewportRotateGizmoHandleDrawData](SceneViewportRotateGizmoHandleDrawData.md) | 单个旋转环 handle 的绘制状态。 | +| [SceneViewportRotateGizmoAngleFillDrawData](SceneViewportRotateGizmoAngleFillDrawData.md) | 当前活动旋转角填充数据。 | +| [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) | 当前帧完整旋转 gizmo 绘制数据。 | +| [SceneViewportRotateGizmoContext](SceneViewportRotateGizmoContext.md) | update / drag 所需输入上下文。 | +| [SceneViewportRotateGizmoHitResult](SceneViewportRotateGizmoHitResult.md) | 旋转 gizmo 命中结果。 | + +## 当前实现行为 + +按 `SceneViewportRotateGizmo.cpp` 的实现: + +- 拖拽开始时会调用 `undoManager.BeginInteractiveChange("Rotate Gizmo")`。 +- 若无法稳定建立世界拖拽平面,会回退到 `screenSpaceDrag` 路径。 +- `View` 环本质上走的是视图相关旋转,不参与 local-space 轴语义。 +- `rotateAroundSharedPivot = true` 时,会把多对象围绕共同 pivot 一起旋转位置。 +- local-space 模式下,非 `View` 轴会把旋转增量作为局部旋转乘到起始姿态上。 + +## 绘制与命中模型 + +- 每个旋转环当前离散成固定数量的线段。 +- 绘制数据里会区分前向可见段和背向段。 +- 活动拖拽时还会生成 `angleFill`,用于在环内显示当前旋转角区域。 + +## 设计说明 + +旋转 gizmo 往往是编辑器最容易“手感差”的控件。当前实现同时准备了世界平面拖拽和屏幕空间回退,说明它在优先保证两个目标: + +- 能正确表达 3D 旋转方向。 +- 在相机视角不理想时,仍然能拖得动。 + +这和成熟商用编辑器非常一致,因为旋转控件如果只依赖单一数学路径,通常会在某些观察角度下失去可用性。 + +## 生命周期与线程语义 + +- 对象由 [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) 持有。 +- 拖拽过程中会缓存多对象的起始位置和起始旋转。 +- [EndDrag](EndDrag.md) / [CancelDrag](CancelDrag.md) 负责提交或取消交互式撤销,并清空活动状态。 + +## 与测试的对应关系 + +`tests/Editor/test_scene_viewport_rotate_gizmo.cpp` 当前覆盖了: + +- `X` 轴旋转环与 `View` 环的可见性和悬停命中。 +- 轴向拖拽会改变对象朝向,并生成 / 回滚交互式撤销。 +- 活动拖拽期间会生成 `angleFill`,并临时重建其它环的可视几何。 +- 边缘视角下会回退到 screen-space rotation。 +- 带缩放父节点的子对象仍能正确旋转。 + +## 当前限制 + +- 当前没有角度吸附、数值输入或显式角度 HUD。 +- 共享 pivot 旋转虽然已支持,但更复杂的多对象 local-space 组合行为仍可能继续演进。 + +## 相关文档 + +- [SceneViewportRotateGizmoAxis](SceneViewportRotateGizmoAxis.md) +- [SceneViewportRotateGizmoContext](SceneViewportRotateGizmoContext.md) +- [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) +- [SceneViewportRotateGizmoHitResult](SceneViewportRotateGizmoHitResult.md) +- [State Queries](StateQueries.md) +- [SceneViewportMath](../SceneViewportMath/SceneViewportMath.md) +- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md) +- [SceneViewportScaleGizmo](../SceneViewportScaleGizmo/SceneViewportScaleGizmo.md) +- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) +- [SceneView Interaction And Gizmo Model](../../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAngleFillDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAngleFillDrawData.md new file mode 100644 index 00000000..87183a04 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAngleFillDrawData.md @@ -0,0 +1,28 @@ +# SceneViewportRotateGizmoAngleFillDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +表示当前活动旋转角区域的填充与轮廓绘制数据。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `axis` | 当前填充对应的旋转轴。 | +| `pivot` | 屏幕空间 pivot。 | +| `arcPoints` | 角度填充扇形边界点。 | +| `arcPointCount` | 当前有效点数量。 | +| `fillColor` | 填充色。 | +| `outlineColor` | 轮廓色。 | +| `visible` | 当前是否需要绘制。 | + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAxis.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAxis.md new file mode 100644 index 00000000..6aba9212 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoAxis.md @@ -0,0 +1,38 @@ +# SceneViewportRotateGizmoAxis + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 定义 + +```cpp +enum class SceneViewportRotateGizmoAxis : uint8_t { + None = 0, + X, + Y, + Z, + View +}; +``` + +## 作用 + +表示当前旋转 gizmo 命中或激活的旋转环。 + +## 枚举值 + +| 值 | 说明 | +|------|------| +| `None` | 没有命中任何旋转环。 | +| `X` | 围绕 X 轴的旋转环。 | +| `Y` | 围绕 Y 轴的旋转环。 | +| `Z` | 围绕 Z 轴的旋转环。 | +| `View` | 面向当前视图的屏幕空间旋转环。 | + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoHitResult](SceneViewportRotateGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoContext.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoContext.md new file mode 100644 index 00000000..563acb93 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoContext.md @@ -0,0 +1,35 @@ +# SceneViewportRotateGizmoContext + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +封装旋转 gizmo 在 update 和拖拽阶段所需的输入上下文。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `overlay` | 当前 Scene View 相机 overlay 数据。 | +| `viewportSize` | 视口尺寸。 | +| `mousePosition` | 当前鼠标位置。 | +| `selectedObject` | 当前主选对象。 | +| `selectedObjects` | 当前全部选中对象。 | +| `pivotWorldPosition` | 旋转 pivot 的世界坐标。 | +| `axisOrientation` | 当前 gizmo 轴向使用的旋转基。 | +| `localSpace` | 是否使用局部空间轴。 | +| `rotateAroundSharedPivot` | 多选时是否围绕共享 pivot 一起旋转位置。 | + +## 当前使用方式 + +- `Update(...)` 用它刷新 draw data 和 hover 状态。 +- `TryBeginDrag(...)` / `UpdateDrag(...)` 用它构建世界拖拽平面或屏幕空间回退路径。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoDrawData.md new file mode 100644 index 00000000..7aba1596 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoDrawData.md @@ -0,0 +1,33 @@ +# SceneViewportRotateGizmoDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +封装当前帧 rotate gizmo 的完整绘制数据,供 gizmo overlay state 构建与 editor overlay frame data 复用。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `visible` | 整个 rotate gizmo 当前是否可见。 | +| `pivot` | 屏幕空间 pivot。 | +| `handles` | `X/Y/Z/View` 四类旋转环的绘制数据。 | +| `angleFill` | 当前旋转拖拽时显示的角度填充区域。 | + +## 当前使用方式 + +- `SceneViewportRotateGizmo::Update(...)` 会刷新这份数据。 +- `SceneViewPanel` 会经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它与当前实体 id 聚合成 overlay submission。 +- transform gizmo provider 再把它转成 `handleRecords` 与 `screenTriangles`。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoHandleDrawData](SceneViewportRotateGizmoHandleDrawData.md) +- [SceneViewportRotateGizmoAngleFillDrawData](SceneViewportRotateGizmoAngleFillDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHandleDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHandleDrawData.md new file mode 100644 index 00000000..e0e1904b --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHandleDrawData.md @@ -0,0 +1,28 @@ +# SceneViewportRotateGizmoHandleDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +描述单个旋转环 handle 在当前帧的绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `axis` | 当前 handle 对应的旋转轴。 | +| `segments` | 固定数量的离散环段绘制数据。 | +| `color` | 该旋转环主色。 | +| `visible` | 当前帧是否可见。 | +| `hovered` | 当前是否悬停。 | +| `active` | 当前是否处于拖拽激活态。 | + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoSegmentDrawData](SceneViewportRotateGizmoSegmentDrawData.md) +- [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHitResult.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHitResult.md new file mode 100644 index 00000000..eb3d35cb --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoHitResult.md @@ -0,0 +1,28 @@ +# SceneViewportRotateGizmoHitResult + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +表示一次旋转 gizmo hit-test 的结果。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `axis` | 命中的旋转环。 | +| `distanceSq` | 命中点到鼠标的平方距离。 | + +## 当前实现行为 + +- 内联 `HasHit()` 只要 `axis != SceneViewportRotateGizmoAxis::None` 就返回 `true`。 +- 当前命中结果统一按最近旋转环表达,不再区分单独的平面或中心 handle 类型。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoAxis](SceneViewportRotateGizmoAxis.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoSegmentDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoSegmentDrawData.md new file mode 100644 index 00000000..dd5b6ac6 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SceneViewportRotateGizmoSegmentDrawData.md @@ -0,0 +1,27 @@ +# SceneViewportRotateGizmoSegmentDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 作用 + +描述旋转环离散后单个线段片段的绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `start` | 线段起点。 | +| `end` | 线段终点。 | +| `startAngle` | 该段起始角度。 | +| `endAngle` | 该段结束角度。 | +| `visible` | 当前线段是否可见。 | +| `frontFacing` | 该段是否位于前向可见半环。 | + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [SceneViewportRotateGizmoHandleDrawData](SceneViewportRotateGizmoHandleDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SetHoveredHandle.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SetHoveredHandle.md new file mode 100644 index 00000000..bf852ab5 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/SetHoveredHandle.md @@ -0,0 +1,29 @@ +# SceneViewportRotateGizmo::SetHoveredHandle + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +void SetHoveredHandle(SceneViewportRotateGizmoAxis axis); +``` + +## 作用 + +允许外部交互系统覆盖当前 hover 轴。 + +## 当前实现行为 + +- 仅在当前没有活动拖拽时生效。 +- 直接写入 `m_hoveredAxis`,然后调用 `RefreshHandleState()` 同步显示状态。 +- 这个入口通常用于外层统一命中仲裁后,把结果灌回 gizmo,而不是依赖它自己内部 hit test。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [EvaluateHit](EvaluateHit.md) +- [Update](Update.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/StateQueries.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/StateQueries.md new file mode 100644 index 00000000..f5c11953 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/StateQueries.md @@ -0,0 +1,49 @@ +# SceneViewportRotateGizmo::State Queries + +**命名空间**: `XCEngine::Editor` + +**类型**: `methods` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +bool IsHoveringHandle() const; +bool IsActive() const; +uint64_t GetActiveEntityId() const; +const SceneViewportRotateGizmoDrawData& GetDrawData() const; +``` + +## 作用 + +提供 rotate gizmo 当前 hover / active 状态、活动实体以及每帧 draw data 的只读访问。 + +## 当前实现行为 + +### `IsHoveringHandle()` + +- 当前实现等价于 `m_hoveredAxis != SceneViewportRotateGizmoAxis::None`。 + +### `IsActive()` + +- 当前实现等价于 `m_activeAxis != SceneViewportRotateGizmoAxis::None`。 +- 表示当前是否存在进行中的旋转拖拽。 + +### `GetActiveEntityId()` + +- 直接返回 `m_activeEntityId`。 +- 未激活拖拽时通常为 `0`。 + +### `GetDrawData()` + +- 返回 `m_drawData` 的常量引用。 +- 该数据由 [Update](Update.md) 维护。 +- 当前主调用链不会让 HUD 直接读取它;`SceneViewPanel` 会先经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它聚合进 overlay submission,最终由 provider 体系转成统一的命中与绘制数据。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [Update](Update.md) +- [SceneViewportRotateGizmoDrawData](SceneViewportRotateGizmoDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/TryBeginDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/TryBeginDrag.md new file mode 100644 index 00000000..fa81fa2c --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/TryBeginDrag.md @@ -0,0 +1,49 @@ +# SceneViewportRotateGizmo::TryBeginDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +bool TryBeginDrag(const SceneViewportRotateGizmoContext& context, IUndoManager& undoManager); +``` + +## 作用 + +在当前 hover 轴上启动一次旋转拖拽,并为交互式撤销缓存初始状态。 + +## 当前实现行为 + +- 只有在以下条件同时满足时才会启动: + - 当前没有活动轴 + - 当前已有 hover 轴 + - `selectedObject` 有效 + - draw data 可见 + - `undoManager` 当前没有待提交的 interactive change +- 会根据当前 hover 轴计算世界旋转轴,并用 `pivotWorldPosition + worldAxis` 构造拖拽平面。 +- 优先尝试通过 `BuildSceneViewportRay(...)` 与拖拽平面求交,得到稳定的世界空间起始方向。 +- 如果世界空间路径不可用,则回退到 screen-space ring angle 方案,用最近环段角度作为起始角。 +- 成功后会调用 `undoManager.BeginInteractiveChange("Rotate Gizmo")`。 +- 会缓存本次拖拽所需状态: + - 活动轴与活动实体 id + - 是否 local-space 旋转 + - 是否 shared-pivot 旋转 + - 世界旋转轴、拖拽平面、起始角 + - 所有参与拖拽对象的起始世界位置与起始世界旋转 +- 若 `selectedObjects` 为空,会自动退回到仅对 `selectedObject` 单对象拖拽。 + +## 返回值 + +- `true`: 成功进入拖拽状态。 +- `false`: 前置条件、命中几何或 interactive undo 任一环节失败。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/Update.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/Update.md new file mode 100644 index 00000000..b47a6a63 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/Update.md @@ -0,0 +1,38 @@ +# SceneViewportRotateGizmo::Update + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +void Update(const SceneViewportRotateGizmoContext& context); +``` + +## 作用 + +刷新当前帧旋转 gizmo 的绘制数据,并根据鼠标位置维护 hover 状态。 + +## 当前实现行为 + +- 先调用内部 `BuildDrawData(context)`,重建四个旋转环和角度填充的绘制数据。 +- 当前没有活动拖拽且鼠标位于视口内时,会调用 `EvaluateHit(context.mousePosition)` 自动计算当前 hover 轴。 +- 当前没有活动拖拽但鼠标已离开视口时,会把 `hoveredAxis` 清回 `None`。 +- 当前处于拖拽中时,会强制把 hover 轴锁定为活动轴,避免拖拽过程中出现视觉跳变。 +- 最后调用 `RefreshHandleState()`,把 hover / active 状态同步进 draw data。 + +## 当前实现边界 + +- `Update(...)` 只负责本帧可视化和 hover 刷新,不会启动拖拽事务。 +- 该方法依赖 `SceneViewportRotateGizmoContext` 里的 overlay、viewportSize、mousePosition 与选中对象信息。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/UpdateDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/UpdateDrag.md new file mode 100644 index 00000000..766fc769 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportRotateGizmo/UpdateDrag.md @@ -0,0 +1,45 @@ +# SceneViewportRotateGizmo::UpdateDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportRotateGizmo.h` + +## 签名 + +```cpp +void UpdateDrag(const SceneViewportRotateGizmoContext& context); +``` + +## 作用 + +根据当前鼠标位置持续更新旋转增量,并把结果写回一个或多个选中对象。 + +## 当前实现行为 + +- 只有在活动轴有效、主选对象未变化、缓存对象数组与起始姿态数组长度一致时才继续。 +- 如果拖拽以 screen-space 模式启动,会继续通过最近环段角度求当前角度。 +- 如果拖拽以世界平面模式启动,会重新构建视口射线,与缓存拖拽平面求交,再把命中方向投影到活动旋转轴的法平面上。 +- 用 `NormalizeSignedAngleRadians(...)` 计算相对起始角的有符号弧度增量。 +- 基于该角度增量同时构造: + - 围绕世界轴的 `worldDeltaRotation` + - 在 local-space 模式下使用的 `localDeltaRotation` +- 对每个参与拖拽对象: + - `rotateAroundSharedPivot = true` 时,先围绕共享 pivot 旋转位置 + - 否则恢复到各自起始世界位置 + - 再按 local-space 或 world-space 规则写回旋转 +- 拖拽中会重新构造 draw data。 +- 当处于 local-space 模式时,会用 `ComputeStableWorldRotation(selectedObject)` 更新可视化轴向,避免旋转过程中环轴方向失稳。 + +## 当前实现边界 + +- 旋转过程中不做角度吸附。 +- 拖拽失败或几何退化时,该帧会直接保持上一帧状态。 + +## 相关文档 + +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/CancelDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/CancelDrag.md new file mode 100644 index 00000000..dd06328d --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/CancelDrag.md @@ -0,0 +1,29 @@ +# SceneViewportScaleGizmo::CancelDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +void CancelDrag(IUndoManager* undoManager = nullptr); +``` + +## 作用 + +取消一次缩放拖拽,并清理当前活动 handle 的缓存状态。 + +## 当前实现行为 + +- 如果传入了 `undoManager` 且当前存在 pending interactive change,会调用 `CancelInteractiveChange()` 回滚本次事务。 +- 同样会清空活动状态。 +- 与 [EndDrag](EndDrag.md) 相比,还会额外把 `hoveredHandle` 一并清空。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [EndDrag](EndDrag.md) +- [TryBeginDrag](TryBeginDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EndDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EndDrag.md new file mode 100644 index 00000000..f4728992 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EndDrag.md @@ -0,0 +1,29 @@ +# SceneViewportScaleGizmo::EndDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +void EndDrag(IUndoManager& undoManager); +``` + +## 作用 + +提交一次缩放拖拽,并清理当前活动 handle 的缓存状态。 + +## 当前实现行为 + +- 当前没有活动 handle 时直接返回。 +- 如果 `undoManager` 仍有 pending interactive change,会调用 `FinalizeInteractiveChange()` 提交缩放结果。 +- 随后清空活动 handle、活动实体 id、起始局部缩放、起始鼠标位置、屏幕方向和视觉缩放缓存。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [CancelDrag](CancelDrag.md) +- [UpdateDrag](UpdateDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EvaluateHit.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EvaluateHit.md new file mode 100644 index 00000000..141f6557 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/EvaluateHit.md @@ -0,0 +1,34 @@ +# SceneViewportScaleGizmo::EvaluateHit + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +SceneViewportScaleGizmoHitResult EvaluateHit(const Math::Vector2& mousePosition) const; +``` + +## 作用 + +提供缩放 gizmo 的命中检测,并返回当前最近命中的 handle。 + +## 当前实现行为 + +- draw data 不可见时直接返回空命中。 +- 会优先检测中心 uniform 方块,命中后立即返回 `Uniform`。 +- 之后会检测每个轴向 cap 方块,优先使用 cap 区域而不是整条线段。 +- 如果 cap 都没命中,才退回到轴向线段距离测试。 +- 这意味着当前缩放 gizmo 的命中优先级是: + - 中心 uniform handle + - 轴向 cap + - 轴向连线 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SetHoveredHandle](SetHoveredHandle.md) +- [SceneViewportScaleGizmoHitResult](SceneViewportScaleGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmo.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmo.md new file mode 100644 index 00000000..6db06918 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmo.md @@ -0,0 +1,107 @@ +# SceneViewportScaleGizmo + +**命名空间**: `XCEngine::Editor` + +**类型**: `class + enum + structs` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +**描述**: Scene View 缩放 gizmo,负责轴向缩放与 uniform 缩放,并把鼠标位移映射到局部缩放值。 + +## 概述 + +`SceneViewportScaleGizmo` 当前比 move / rotate 更克制一些。它支持的 handle 是: + +- `X` +- `Y` +- `Z` +- `Uniform` + +但从上下文结构可以看出,它当前只对 `selectedObject` 单对象工作,没有 move / rotate 那种多对象数组上下文。 + +## 当前实现行为 + +按 `SceneViewportScaleGizmo.cpp` 的实现: + +- 拖拽开始时会调用 `undoManager.BeginInteractiveChange("Scale Gizmo")`。 +- 轴向缩放会把鼠标位移投影到活动轴在屏幕上的方向上。 +- 如果现成的屏幕线段方向不可用,会退回到 [ProjectSceneViewportAxisDirectionAtPoint](../SceneViewportMath/SceneViewportMath.md) 估算方向。 +- uniform 缩放使用 `mouseDelta.x - mouseDelta.y` 作为统一因子。 +- 所有缩放都会经过最小值钳制,避免局部缩放降到 `0` 或负数。 + +## 公开类型 + +| 类型 | 说明 | +|------|------| +| [SceneViewportScaleGizmoHandle](SceneViewportScaleGizmoHandle.md) | 缩放 gizmo 的 handle 枚举。 | +| [SceneViewportScaleGizmoAxisHandleDrawData](SceneViewportScaleGizmoAxisHandleDrawData.md) | 单个轴向缩放 handle 的绘制状态。 | +| [SceneViewportScaleGizmoCenterHandleDrawData](SceneViewportScaleGizmoCenterHandleDrawData.md) | 中心 uniform handle 的绘制状态。 | +| [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) | 当前帧完整缩放 gizmo 绘制数据。 | +| [SceneViewportScaleGizmoContext](SceneViewportScaleGizmoContext.md) | update / drag 阶段输入上下文。 | +| [SceneViewportScaleGizmoHitResult](SceneViewportScaleGizmoHitResult.md) | 缩放 gizmo 的命中结果。 | + +## 公开 API + +### 交互主流程 + +- [Update](Update.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) + +### 状态查询 + +- [State Queries](StateQueries.md) + +## 与 Transform 工具模式的关系 + +`SceneViewPanel` 在 `Transform` 组合工具模式下会把 `uniformOnly = true` 传进 context。按当前实现,这意味着: + +- 组合工具不会暴露完整三轴缩放 handle。 +- 当前更像“Move + Rotate + 中心统一缩放”的复合工具。 + +## 设计说明 + +缩放 gizmo 的交互通常比位移和旋转更容易失控,因为负缩放、极小缩放和轴向投影不稳定都会让操作体验变差。当前实现明显优先了“可控”和“安全”: + +- 强制正缩放下界。 +- 轴向缩放只沿屏幕可感知方向变化。 +- 组合工具模式下进一步收窄成 uniform scale。 + +## 生命周期与线程语义 + +- 对象由 [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) 持有。 +- 当前只记录单个对象的起始 `localScale`,不是多对象事务。 +- 主流程可参考 [Update](Update.md)、[TryBeginDrag](TryBeginDrag.md)、[UpdateDrag](UpdateDrag.md)、[EndDrag](EndDrag.md) 与 [CancelDrag](CancelDrag.md)。 + +## 与测试的对应关系 + +`tests/Editor/test_scene_viewport_scale_gizmo.cpp` 当前覆盖了: + +- `X` 轴缩放 handle 的悬停命中。 +- 带缩放父节点的子对象轴向缩放只改动对应局部缩放分量。 +- 轴向拖拽期间 handle 长度会临时变化,结束后恢复。 +- 中心 handle 会触发 uniform 缩放,并生成 / 回滚交互式撤销。 +- 旋转对象的 `X` 轴 handle 会沿投影后的局部 `Right` 方向摆放。 + +## 当前限制 + +- 当前没有多对象缩放。 +- 当前没有非等比多对象共享中心缩放策略。 +- 没有数值输入、吸附或比例锁 UI。 + +## 相关文档 + +- [SceneViewportScaleGizmoHandle](SceneViewportScaleGizmoHandle.md) +- [SceneViewportScaleGizmoContext](SceneViewportScaleGizmoContext.md) +- [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) +- [SceneViewportScaleGizmoHitResult](SceneViewportScaleGizmoHitResult.md) +- [State Queries](StateQueries.md) +- [SceneViewportMath](../SceneViewportMath/SceneViewportMath.md) +- [SceneViewportMoveGizmo](../SceneViewportMoveGizmo/SceneViewportMoveGizmo.md) +- [SceneViewportRotateGizmo](../SceneViewportRotateGizmo/SceneViewportRotateGizmo.md) +- [SceneViewPanel](../../panels/SceneViewPanel/SceneViewPanel.md) +- [SceneView Interaction And Gizmo Model](../../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoAxisHandleDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoAxisHandleDrawData.md new file mode 100644 index 00000000..12c5f47e --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoAxisHandleDrawData.md @@ -0,0 +1,30 @@ +# SceneViewportScaleGizmoAxisHandleDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 作用 + +描述单个轴向缩放 handle 在当前帧的绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `handle` | 当前轴向 handle 类型。 | +| `start` | 屏幕空间起点。 | +| `end` | 屏幕空间终点。 | +| `capCenter` | 端帽中心点。 | +| `capHalfSize` | 端帽半尺寸。 | +| `color` | 轴向颜色。 | +| `visible` | 当前帧是否可见。 | +| `hovered` | 当前是否悬停。 | +| `active` | 当前是否处于拖拽激活态。 | + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoCenterHandleDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoCenterHandleDrawData.md new file mode 100644 index 00000000..9a2e0e08 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoCenterHandleDrawData.md @@ -0,0 +1,28 @@ +# SceneViewportScaleGizmoCenterHandleDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 作用 + +描述中心 uniform 缩放 handle 的绘制状态。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `center` | 中心方块的屏幕空间中心点。 | +| `halfSize` | 方块半尺寸。 | +| `fillColor` | 填充色。 | +| `outlineColor` | 轮廓色。 | +| `visible` | 当前帧是否可见。 | +| `hovered` | 当前是否悬停。 | +| `active` | 当前是否正在拖拽。 | + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoContext.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoContext.md new file mode 100644 index 00000000..2b524965 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoContext.md @@ -0,0 +1,33 @@ +# SceneViewportScaleGizmoContext + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 作用 + +封装缩放 gizmo 在 update 和拖拽阶段所需的输入上下文。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `overlay` | 当前 Scene View 相机 overlay 数据。 | +| `viewportSize` | 视口尺寸。 | +| `mousePosition` | 当前鼠标位置。 | +| `selectedObject` | 当前主选对象。 | +| `pivotWorldPosition` | gizmo pivot 世界坐标。 | +| `axisOrientation` | gizmo 轴向所使用的旋转基。 | +| `uniformOnly` | 是否只显示和允许中心统一缩放 handle。 | + +## 当前使用方式 + +- `Update(...)` 会用它刷新 draw data。 +- `TryBeginDrag(...)` / `UpdateDrag(...)` 会用它将鼠标位移映射到局部缩放值。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoDrawData.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoDrawData.md new file mode 100644 index 00000000..4cd32ab1 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoDrawData.md @@ -0,0 +1,32 @@ +# SceneViewportScaleGizmoDrawData + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 作用 + +封装当前帧 scale gizmo 的完整绘制数据,供 gizmo overlay state 构建与 editor overlay frame data 复用。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `visible` | 整个 scale gizmo 当前是否可见。 | +| `axisHandles` | 三个轴向缩放 handle 的绘制数据。 | +| `centerHandle` | 中心 uniform scale handle 的绘制数据。 | + +## 当前使用方式 + +- `SceneViewportScaleGizmo::Update(...)` 会刷新这份数据。 +- `SceneViewPanel` 会经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它与当前实体 id 聚合成 overlay submission。 +- transform gizmo provider 再把它转成 `handleRecords` 与 `screenTriangles`。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoAxisHandleDrawData](SceneViewportScaleGizmoAxisHandleDrawData.md) +- [SceneViewportScaleGizmoCenterHandleDrawData](SceneViewportScaleGizmoCenterHandleDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHandle.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHandle.md new file mode 100644 index 00000000..b15915c0 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHandle.md @@ -0,0 +1,38 @@ +# SceneViewportScaleGizmoHandle + +**命名空间**: `XCEngine::Editor` + +**类型**: `enum class` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 定义 + +```cpp +enum class SceneViewportScaleGizmoHandle : uint8_t { + None = 0, + X, + Y, + Z, + Uniform +}; +``` + +## 作用 + +表示缩放 gizmo 当前命中或激活的 handle。 + +## 枚举值 + +| 值 | 说明 | +|------|------| +| `None` | 没有命中任何 handle。 | +| `X` | X 轴缩放。 | +| `Y` | Y 轴缩放。 | +| `Z` | Z 轴缩放。 | +| `Uniform` | 中心统一缩放 handle。 | + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoHitResult](SceneViewportScaleGizmoHitResult.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHitResult.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHitResult.md new file mode 100644 index 00000000..9f86e40a --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SceneViewportScaleGizmoHitResult.md @@ -0,0 +1,28 @@ +# SceneViewportScaleGizmoHitResult + +**命名空间**: `XCEngine::Editor` + +**类型**: `struct` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 作用 + +表示一次缩放 gizmo hit-test 的结果。 + +## 字段说明 + +| 字段 | 说明 | +|------|------| +| `handle` | 命中的缩放 handle。 | +| `distanceSq` | 命中点到鼠标的平方距离。 | + +## 当前实现行为 + +- 内联 `HasHit()` 只要 `handle != None` 就返回 `true`。 +- 当前命中模型不区分轴向和平面,而是统一收敛到单个 `SceneViewportScaleGizmoHandle`。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [SceneViewportScaleGizmoHandle](SceneViewportScaleGizmoHandle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SetHoveredHandle.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SetHoveredHandle.md new file mode 100644 index 00000000..0033239a --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/SetHoveredHandle.md @@ -0,0 +1,28 @@ +# SceneViewportScaleGizmo::SetHoveredHandle + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +void SetHoveredHandle(SceneViewportScaleGizmoHandle handle); +``` + +## 作用 + +允许外层输入系统直接覆盖当前 hover handle。 + +## 当前实现行为 + +- 当前存在活动 handle 时不会覆盖内部 hover 状态。 +- 当前没有拖拽时,会直接写入 `m_hoveredHandle` 并刷新 draw data 状态。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [EvaluateHit](EvaluateHit.md) +- [Update](Update.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/StateQueries.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/StateQueries.md new file mode 100644 index 00000000..b3a7ed4b --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/StateQueries.md @@ -0,0 +1,49 @@ +# SceneViewportScaleGizmo::State Queries + +**命名空间**: `XCEngine::Editor` + +**类型**: `methods` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +bool IsHoveringHandle() const; +bool IsActive() const; +uint64_t GetActiveEntityId() const; +const SceneViewportScaleGizmoDrawData& GetDrawData() const; +``` + +## 作用 + +提供 scale gizmo 当前 hover / active 状态、活动实体以及每帧 draw data 的只读访问。 + +## 当前实现行为 + +### `IsHoveringHandle()` + +- 当前实现等价于 `m_hoveredHandle != SceneViewportScaleGizmoHandle::None`。 + +### `IsActive()` + +- 当前实现等价于 `m_activeHandle != SceneViewportScaleGizmoHandle::None`。 +- 表示当前是否存在进行中的缩放拖拽。 + +### `GetActiveEntityId()` + +- 直接返回 `m_activeEntityId`。 +- 未激活拖拽时通常为 `0`。 + +### `GetDrawData()` + +- 返回 `m_drawData` 的常量引用。 +- 该数据由 [Update](Update.md) 维护。 +- 当前主调用链不会让 HUD 直接读取它;`SceneViewPanel` 会先经由 [SceneViewportTransformGizmoCoordinator](../SceneViewportTransformGizmoCoordinator/SceneViewportTransformGizmoCoordinator.md) 把它聚合进 overlay submission,最终由 provider 体系转成统一的命中与绘制数据。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [Update](Update.md) +- [SceneViewportScaleGizmoDrawData](SceneViewportScaleGizmoDrawData.md) +- [SceneViewportOverlayHandleBuilder](../SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/TryBeginDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/TryBeginDrag.md new file mode 100644 index 00000000..baff6990 --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/TryBeginDrag.md @@ -0,0 +1,48 @@ +# SceneViewportScaleGizmo::TryBeginDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +bool TryBeginDrag(const SceneViewportScaleGizmoContext& context, IUndoManager& undoManager); +``` + +## 作用 + +在当前 hover 的缩放 handle 上启动一次缩放拖拽,并缓存起始局部缩放值。 + +## 当前实现行为 + +- 只有在以下条件成立时才会进入拖拽: + - 当前没有活动 handle + - 当前已有 hover handle + - `selectedObject` 有效 + - draw data 可见 + - `undoManager` 当前没有 pending interactive change +- 若当前 handle 不是 `Uniform`: + - 先读取对应轴向 handle 的屏幕线段方向 + - 若线段方向退化为零,再调用 `ProjectSceneViewportAxisDirectionAtPoint(...)` 用世界轴投影补算 +- 成功后调用 `undoManager.BeginInteractiveChange("Scale Gizmo")`。 +- 会缓存: + - 活动 handle 与活动实体 id + - 起始 `localScale` + - 起始鼠标位置 + - 活动屏幕方向 + - 当前可视化缩放因子,初始为 `Vector3::One()` + +## 返回值 + +- `true`: 已成功进入缩放拖拽。 +- `false`: 前置条件、轴向投影或 interactive undo 初始化失败。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [UpdateDrag](UpdateDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/Update.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/Update.md new file mode 100644 index 00000000..c6afb3fc --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/Update.md @@ -0,0 +1,33 @@ +# SceneViewportScaleGizmo::Update + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +void Update(const SceneViewportScaleGizmoContext& context); +``` + +## 作用 + +刷新当前帧缩放 gizmo 的绘制数据,并维护 hover handle。 + +## 当前实现行为 + +- 先调用 `BuildDrawData(context)` 重建三轴缩放 handle 与中心 uniform handle 的绘制数据。 +- 当前没有活动拖拽且鼠标位于视口内时,会调用 `EvaluateHit(context.mousePosition)` 自动命中当前 handle。 +- 当前没有活动拖拽但鼠标已离开视口时,会把 `hoveredHandle` 清回 `None`。 +- 当前已经处于拖拽中时,会把 hover handle 锁定为活动 handle。 +- 最后通过 `RefreshHandleState()` 把 hovered / active 状态同步回 draw data。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [UpdateDrag](UpdateDrag.md) +- [EvaluateHit](EvaluateHit.md) +- [SetHoveredHandle](SetHoveredHandle.md) diff --git a/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/UpdateDrag.md b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/UpdateDrag.md new file mode 100644 index 00000000..1fc4081f --- /dev/null +++ b/docs/api/XCEngine/Editor/Viewport/SceneViewportScaleGizmo/UpdateDrag.md @@ -0,0 +1,42 @@ +# SceneViewportScaleGizmo::UpdateDrag + +**命名空间**: `XCEngine::Editor` + +**类型**: `method` + +**源文件**: `editor/src/Viewport/SceneViewportScaleGizmo.h` + +## 签名 + +```cpp +void UpdateDrag(const SceneViewportScaleGizmoContext& context); +``` + +## 作用 + +根据鼠标位移持续更新单对象的局部缩放,并维护拖拽中的视觉反馈。 + +## 当前实现行为 + +- 只有在活动 handle 有效且主选对象 id 未变化时才会继续。 +- 会先计算 `mouseDelta = currentMouse - startMouse`,再从 `m_dragStartLocalScale` 出发生成本帧新缩放值。 +- `Uniform` 缩放路径: + - 使用 `mouseDelta.x - mouseDelta.y` 作为统一像素增量 + - 计算统一缩放因子后同时更新 `x / y / z` +- 轴向缩放路径: + - 把鼠标位移投影到缓存的 `m_activeScreenDirection` + - 只修改当前活动轴对应的局部缩放分量 +- 所有结果都会经过最小正缩放钳制,避免零缩放或负缩放。 +- 写回 `selectedObject->GetTransform()->SetLocalScale(localScale)` 后,还会更新 `m_dragCurrentVisualScale`,用于拖拽中的 gizmo 可视化反馈。 + +## 当前实现边界 + +- 当前只处理单对象缩放,不会批量更新多选对象。 +- 轴向缩放完全基于屏幕方向投影,不是世界平面求交模型。 + +## 相关文档 + +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo.md) +- [TryBeginDrag](TryBeginDrag.md) +- [EndDrag](EndDrag.md) +- [CancelDrag](CancelDrag.md) diff --git a/docs/api/XCEngine/Editor/Viewport/Viewport.md b/docs/api/XCEngine/Editor/Viewport/Viewport.md index 86f72709..27ebde9d 100644 --- a/docs/api/XCEngine/Editor/Viewport/Viewport.md +++ b/docs/api/XCEngine/Editor/Viewport/Viewport.md @@ -35,6 +35,12 @@ 把 HUD 命中与 overlay handle 命中合并成统一交互结果。 - [SceneViewportInteractionActions](SceneViewportInteractionActions/SceneViewportInteractionActions.md) 把交互结果折叠成 hover / click action,并分发 selection / orientation 对齐。 +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo/SceneViewportMoveGizmo.md) + 处理轴向 / 平面位移 gizmo 的绘制数据、命中与多对象拖拽事务。 +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo/SceneViewportRotateGizmo.md) + 处理旋转环、视图环、共享 pivot 旋转和交互式撤销。 +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo/SceneViewportScaleGizmo.md) + 处理轴向缩放与 uniform 缩放,并把鼠标位移映射到局部缩放值。 - [SceneViewportOverlayHandleBuilder](SceneViewportOverlayHandleBuilder/SceneViewportOverlayHandleBuilder.md) 把 gizmo overlay state 转成 `screenTriangles` 与 `handleRecords`。 - [SceneViewportTransformGizmoFrameBuilder](SceneViewportTransformGizmoFrameBuilder/SceneViewportTransformGizmoFrameBuilder.md) @@ -64,4 +70,7 @@ - [ViewportObjectIdPicker](ViewportObjectIdPicker/ViewportObjectIdPicker.md) - [SceneViewportHudOverlay](SceneViewportHudOverlay/SceneViewportHudOverlay.md) - [SceneViewportOrientationGizmo](SceneViewportOrientationGizmo/SceneViewportOrientationGizmo.md) +- [SceneViewportMoveGizmo](SceneViewportMoveGizmo/SceneViewportMoveGizmo.md) +- [SceneViewportRotateGizmo](SceneViewportRotateGizmo/SceneViewportRotateGizmo.md) +- [SceneViewportScaleGizmo](SceneViewportScaleGizmo/SceneViewportScaleGizmo.md) - [SceneView Interaction And Gizmo Model](../../../_guides/Editor/SceneView-Interaction-And-Gizmo-Model.md)