// // 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 // ImVec2(RequestPickAt 签名) #include #include // 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 不给游戏侧(Editor::BlockingMouse) // ---- 自绘缩放 gizmo(op==SCALE 整体不走 ImGuizmo)---- // 库内缩放的 hover/拖拽依赖"法线=轴"平面求交:正对视角(轴⊥ // 相机连线)时求交分子恒 0 → 杆抓不到、数值随机猛变;轴∥视线 // 时又无屏幕位移。submodule 禁改,AxisMask 只能"藏"不能"补" // → 调用层整体自绘三轴杆 + 中心等比方块(纯屏幕空间数学,任意 // 视角良构),实现见 ViewportPanel.cpp ScaleGizmoSelf bool scaleDragActive = false; // 自绘缩放拖拽中 int scaleDragAxis = -1; // 拖拽目标:0/1/2 轴;-2 = 中心等比 bool scaleHover = false; // 本帧悬停/拖拽自绘手柄 → 抑制 pick float scaleStartMouse[2] = {0.0f, 0.0f}; // 拖拽起始鼠标(屏幕系) float scaleStartDist = 0.0f; // 起始鼠标到杆心距离(径向映射用) float scaleStartScale[3] = {1.0f, 1.0f, 1.0f}; // 拖拽起始 scale }; class ViewportPanel { public: // 返回值:本帧拾取命中的实体(无点击/未命中 = nullopt 或 null); // Editor 据此 SelectEntity(面板不持有选中状态) std::optional 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