Files
HelloVulkan/App/editor/ViewportPanel.h
T
atdunbg 83c1600947 feat: Gizmo local/world 空间切换 + Ctrl 吸附 + Inspector 轴色手输行
- GizmoState.localSpace(默认 local,模型轴旋转直观),T 键切换
  Manipulate 的 LOCAL/WORLD 模式;无父层级两模式 world 矩阵同源,
  decompose 写回链路不变
- Ctrl 按住吸附(UE Grid Snap 语义):平移 0.25m / 旋转 15° /
  缩放 0.1x;ImGuizmo 约定旋转 snap 单位为弧度
- 视口左上角 drawlist 叠加状态提示(Space/Snap,不占布局行)
- Inspector Transform 三行升级 UE 风轴色输入行(对齐 Gizmo 轴色):
  拖拽粗调 + Ctrl+Click 键入精确值
2026-10-03 00:56:27 +08:00

60 lines
2.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// ViewportPanel:场景渲染输出面板。
//
// tonemap 输出经 ImGui::Image 显示(Editor 模式),并提供
// Editor Viewport / Fullscreen 显示模式切换。面板可用区域
// (物理像素)上报为渲染分辨率 → 画面精确填满面板。
//
// 点击拾取(UE 式 GPU HitProxy):单击 → NDC 请求 id 渲染;结果
// 由 Draw 每帧轮询取走(像素级,与视觉画面一致)。
//
#ifndef HELLOVULKAN_VIEWPORTPANEL_H
#define HELLOVULKAN_VIEWPORTPANEL_H
#include "EditorContext.h"
#include <imgui.h> // ImVec2(RequestPickAt 签名)
#include <entt/entt.hpp>
#include <optional>
// Viewport 面板每帧上报的输入焦点状态(Hazel 模式:编辑器据此决定
// 游戏侧输入是否放行——悬停/持焦 Viewport 才拥有 WASD/鼠标)
struct ViewportInputState {
bool hovered = false; // 鼠标悬停在 Viewport 面板上
bool focused = false; // Viewport 面板持有键盘焦点
};
// Gizmo 交互状态(Editor 持有、ViewportPanel 写):
// op 取 ImGuizmo::OPERATION 位掩码(TRANSLATE=7=三轴位或运算,非 0
// 起始枚举;0 = 无任何轴位 → Gizmo 完全不绘制),int 存储避免本
// 头文件 include ImGuizmo.h(拖入 imgui 宏依赖顺序)
// W/E/R 切换 op、T 切换 local/world 空间(UE 语义);dragging 拉起
// Editor::BlockingMouse 门控
struct GizmoState {
int op = 7; // ImGuizmo::TRANSLATE(TRANSLATE_X|Y|Z)
bool localSpace = true; // 操纵空间:true=模型轴(旋转/缩放语义),
// T 键切 world
bool dragging = false; // 拖拽中(IsUsing)→ 鼠标归 Gizmo 不给游戏侧
};
class ViewportPanel {
public:
// 返回值:本帧拾取命中的实体(无点击/未命中 = nullopt 或 null);
// Editor 据此 SelectEntity(面板不持有选中状态)
std::optional<entt::entity> Draw(const EditorContext& ctx,
ViewportInputState& out,
GizmoState& gizmo,
entt::entity selected) const;
private:
// Image 区域内的鼠标位置 → NDC → Renderer::RequestPick
//(结果下一帧由 Draw 轮询 TakePickResult 取走)
void RequestPickAt(const EditorContext& ctx, const ImVec2& size) const;
// 命中打印:实体名 + collider 参数对照(诊断物理盒 ≠ 视觉用)
static void LogPick(const EditorContext& ctx, entt::entity e);
};
#endif //HELLOVULKAN_VIEWPORTPANEL_H