diff --git a/App/main.cpp b/App/main.cpp index f996316..fa05dae 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -71,8 +71,7 @@ namespace if (GetRenderer().GetDisplayMode() == kDisplayViewport && !m_Editor->IsPlaying()) { - GetRenderer().GetEditorCamera().Update(GetWindow(), - frameTime.UnscaledDt()); + GetRenderer().GetEditorCamera().Update(frameTime.UnscaledDt()); } } diff --git a/Engine/include/Engine/Core/Input.h b/Engine/include/Engine/Core/Input.h index 829b351..0de11e9 100644 --- a/Engine/include/Engine/Core/Input.h +++ b/Engine/include/Engine/Core/Input.h @@ -17,6 +17,8 @@ #include +#include "Engine/Core/Types.h" + namespace Engine { class Window; @@ -78,12 +80,29 @@ namespace Engine { Middle = 2, }; - // 装配:Application 构造时自动调用(后端 Window 就绪后) - void Init(const Window& window); + // 装配:Application 构造时自动调用(后端 Window 就绪后)。 + // 非 const:门面含状态设置(光标捕获),不只是查询 + void Init(Window& window); // 轮询查询(UI 捕获对应输入时返回 false——游戏侧静默) bool IsKeyDown(Key key); bool IsMouseButtonDown(MouseButton button); + + // ---- 光标捕获(自由视角三件套:隐藏光标 + 无界鼠标增量 + + // 滚轮增量)。语义沿 Window 后端:捕获时光标隐藏、位置锁定 + // 窗口中心,GetMouseDelta 出无界增量;重复设置同值无操作 ---- + + // 隐藏并锁定光标(自由视角/环绕中);false 恢复正常光标 + void SetCursorCaptured(bool captured); + bool IsCursorCaptured(); + + // 帧间光标增量(无界,捕获态下才有意义;窗口尺寸/模式变化 + // 由后端参考点重置防跳变) + void GetMouseDelta(f32& dx, f32& dy); + + // 滚轮增量(上行 = +1,一档 ≈1):读后清零。UI 捕获鼠标 + //(面板悬停)时不累积——滚轮归 ImGui + f32 ConsumeScrollDelta(); } } // namespace Engine diff --git a/Engine/include/Engine/Renderer/Camera.h b/Engine/include/Engine/Renderer/Camera.h index c446b5a..a4d41a4 100644 --- a/Engine/include/Engine/Renderer/Camera.h +++ b/Engine/include/Engine/Renderer/Camera.h @@ -26,15 +26,15 @@ namespace Engine { - class Window; namespace ECS { struct TransformComponent; } class Camera { public: - // 输入驱动。flyRequiresRMB=true(编辑器模式):移动键仅在 RMB - // 按住时生效——解决与 Gizmo W/E/R 工具热键的键位冲突(UE 语义: - // 飞行时键盘归相机)。全部写回传入的 transform - void Update(Window& window, ECS::TransformComponent& transform, + // 输入驱动(键鼠查询统一走 Input 门面,零 Window 依赖)。 + // flyRequiresRMB=true(编辑器模式):移动键仅在 RMB 按住时生效 + // ——解决与 Gizmo W/E/R 工具热键的键位冲突(UE 语义:飞行时 + // 键盘归相机)。全部写回传入的 transform + void Update(ECS::TransformComponent& transform, f32 deltaTime, bool flyRequiresRMB = false); // 焦点选中(UE frame-selection):pivot 设为 point,相机沿当前 diff --git a/Engine/include/Engine/Renderer/EditorCamera.h b/Engine/include/Engine/Renderer/EditorCamera.h index 42101cf..8f184a8 100644 --- a/Engine/include/Engine/Renderer/EditorCamera.h +++ b/Engine/include/Engine/Renderer/EditorCamera.h @@ -22,8 +22,6 @@ namespace Engine { - class Window; - class EditorCamera { public: EditorCamera() @@ -38,10 +36,10 @@ namespace Engine { // 每帧输入驱动(编辑器形态由 Application 调用;游戏形态不调 // 即静止)。flyRequiresRMB 恒 true:编辑器移动键只在 RMB 按住 // 时生效(W/E/R 归 Gizmo,UE 语义)。暂停(timeScale=0)时 - // 仍可飞行——调用方传 unscaled dt - void Update(Window& window, f32 deltaTime) + // 仍可飞行——调用方传 unscaled dt。键鼠/光标捕获统一走 Input + void Update(f32 deltaTime) { - m_Controller.Update(window, m_Transform, deltaTime, + m_Controller.Update(m_Transform, deltaTime, /*flyRequiresRMB=*/true); m_Transform.Compose(); // World() 是渲染/Gizmo 读源,随写随算 } diff --git a/Engine/src/Core/Input.cpp b/Engine/src/Core/Input.cpp index 88b4c52..b0a5a57 100644 --- a/Engine/src/Core/Input.cpp +++ b/Engine/src/Core/Input.cpp @@ -10,11 +10,12 @@ namespace Engine { namespace { // Application 生命周期内有效(成员析构序:Input 无状态依赖, - // 仅 Application::Run 期间被查询) - const Window* s_Window = nullptr; + // 仅 Application::Run 期间被查询)。非 const:门面含 + // 光标捕获等状态设置,不只查询 + Window* s_Window = nullptr; } - void Init(const Window& window) + void Init(Window& window) { s_Window = &window; } @@ -31,5 +32,33 @@ namespace Engine { s_Window->IsMouseButtonPressed(static_cast(button)); } + void SetCursorCaptured(const bool captured) + { + if (s_Window != nullptr) + { + s_Window->SetCursorCaptured(captured); + } + } + + bool IsCursorCaptured() + { + return s_Window != nullptr && s_Window->IsCursorCaptured(); + } + + void GetMouseDelta(f32& dx, f32& dy) + { + if (s_Window != nullptr) + { + s_Window->GetMouseDelta(dx, dy); + return; + } + dx = dy = 0.0f; + } + + f32 ConsumeScrollDelta() + { + return s_Window != nullptr ? s_Window->ConsumeScrollDelta() : 0.0f; + } + } } // namespace Engine diff --git a/Engine/src/Renderer/Camera.cpp b/Engine/src/Renderer/Camera.cpp index 7f14e1c..7bfc912 100644 --- a/Engine/src/Renderer/Camera.cpp +++ b/Engine/src/Renderer/Camera.cpp @@ -27,7 +27,7 @@ namespace Engine { } } - void Camera::Update(Window& window, ECS::TransformComponent& transform, + void Camera::Update(ECS::TransformComponent& transform, const f32 deltaTime, const bool flyRequiresRMB) { // ---- 输入模式(UE Scene view 语义):RMB=自由视角(鼠标转向 @@ -41,13 +41,13 @@ namespace Engine { if (wantLook || wantOrbit) { - if (!window.IsCursorCaptured()) + if (!Input::IsCursorCaptured()) { - window.SetCursorCaptured(true); + Input::SetCursorCaptured(true); } f32 mouseDX = 0, mouseDY = 0; - window.GetMouseDelta(mouseDX, mouseDY); + Input::GetMouseDelta(mouseDX, mouseDY); if (mouseDX != 0 || mouseDY != 0) { @@ -105,9 +105,9 @@ namespace Engine { } } } - else if (window.IsCursorCaptured()) + else if (Input::IsCursorCaptured()) { - window.SetCursorCaptured(false); + Input::SetCursorCaptured(false); } // 基向量由(可能已更新的)实体旋转决定(本地 -Z 为视线方向) @@ -130,7 +130,7 @@ namespace Engine { // ---- 滚轮推拉:有 pivot 时改环绕距离(指数步进,近处精细/ // 远处大步);无 pivot 时沿视线平移 ---- - const f32 wheel = window.ConsumeScrollDelta(); + const f32 wheel = Input::ConsumeScrollDelta(); if (m_MouseLookEnabled && wheel != 0.0f) { if (m_HasPivot)