camera: UE Scene-view semantics — RMB fly, MMB focus-orbit, wheel dolly, F focus
Key conflict fix (UE semantics): while RMB is held the keyboard belongs to the camera, so WASD no longer collides with the gizmo W/E/R tool hotkeys. Editor mode gates fly movement behind RMB; game mode keeps always-on WASD. Viewport tool hotkeys (W/E/R/T/F) are suppressed while RMB is held. Focus orbit (pivot): MMB drag rotates the camera around a pivot keeping distance; first orbit picks a pivot 5m ahead on the view ray. Shift+MMB pans in screen plane (camera and pivot move together). Mouse wheel dollies toward/away from the pivot with exponential steps (no pivot: move along view ray). F focuses the selected entity (frame-selection): pivot set to its position, camera slides along the view ray; orbit distance persists. Window gains a polled scroll-delta channel (ConsumeScrollDelta) that respects ImGui mouse capture; Camera::Update mutates orbit state (no longer const).
This commit is contained in:
@@ -67,6 +67,10 @@ namespace Engine {
|
||||
bool IsMouseButtonPressed(int button) const;
|
||||
void GetMouseDelta(float& dx, float& dy) const;
|
||||
|
||||
// 轮询式滚轮增量(上行 = +1,一档 ≈1):读后清零。UI 捕获鼠标
|
||||
//(面板悬停)时不累积——滚轮归 ImGui
|
||||
float ConsumeScrollDelta();
|
||||
|
||||
// 光标捕获(自由视角):DISABLED 隐藏光标出无界增量,NORMAL 恢复。
|
||||
// 重复设置同值无操作;切换后鼠标增量参考点重置(防跳变)
|
||||
void SetCursorCaptured(bool captured);
|
||||
@@ -92,6 +96,7 @@ namespace Engine {
|
||||
mutable bool m_FirstMouse = true;
|
||||
mutable double m_LastMouseX = 0.0;
|
||||
mutable double m_LastMouseY = 0.0;
|
||||
mutable float m_ScrollAccum = 0.0f; // 滚轮累积(ConsumeScrollDelta)
|
||||
|
||||
// GLFW 静态回调(通过 window user pointer 找回 this)
|
||||
static void FramebufferResizeCallback(GLFWwindow* window, int width, int height);
|
||||
|
||||
@@ -4,9 +4,18 @@
|
||||
// Camera:独立的相机模块。
|
||||
//
|
||||
// 设计(Transform 单一事实源):相机的位置与朝向完全由实体上的
|
||||
// TransformComponent 承载——Update 把输入直接写回 transform(末尾
|
||||
// Compose),视图矩阵 = 实体世界矩阵的逆(本地 -Z 为视线方向)。
|
||||
// 相机类自身不保存任何位姿状态,杜绝"位置两套来源"的脱节。
|
||||
// TransformComponent 承载——Update 把输入直接写回 transform,视图
|
||||
// 矩阵 = 实体世界矩阵的逆(本地 -Z 为视线方向)。相机类自身只保存
|
||||
// 焦点环绕(pivot orbit)状态(pivot/距离),杜绝位姿两套来源。
|
||||
//
|
||||
// 交互(UE Scene view 语义):
|
||||
// RMB 按住 自由视角:鼠标转向 + WASD/Space/Shift 飞行
|
||||
// (编辑器模式下 RMB 按住期间键盘归相机,W/E/R 不切
|
||||
// Gizmo——键位冲突的解法与 UE 一致)
|
||||
// MMB 拖拽 焦点环绕:绕 pivot 转向,距离不变
|
||||
// Shift+MMB 屏幕平面平移(相机与 pivot 同步移动)
|
||||
// 滚轮 推拉:改环绕距离(有 pivot 时指数步进)
|
||||
// F(面板侧) 焦点选中实体(ViewportPanel 调 FocusOn)
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_CAMERA_H
|
||||
@@ -22,9 +31,15 @@ namespace Engine {
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
// 输入驱动:WASD/Space/Shift 移动 + 按住右键鼠标视角。
|
||||
// 全部写回传入的 transform,有变更才 Compose。
|
||||
void Update(Window& window, ECS::TransformComponent& transform, f32 deltaTime) const;
|
||||
// 输入驱动。flyRequiresRMB=true(编辑器模式):移动键仅在 RMB
|
||||
// 按住时生效——解决与 Gizmo W/E/R 工具热键的键位冲突(UE 语义:
|
||||
// 飞行时键盘归相机)。全部写回传入的 transform
|
||||
void Update(Window& window, ECS::TransformComponent& transform,
|
||||
f32 deltaTime, bool flyRequiresRMB = false);
|
||||
|
||||
// 焦点选中(UE frame-selection):pivot 设为 point,相机沿当前
|
||||
// 视线平移对准;环绕距离沿用当前值(初始 5m,滚轮可改)
|
||||
void FocusOn(ECS::TransformComponent& transform, const glm::vec3& point);
|
||||
|
||||
// 相机视图 = 实体世界矩阵的逆(要求 transform 已 Compose)
|
||||
glm::mat4 GetView(const ECS::TransformComponent& transform) const;
|
||||
@@ -35,8 +50,7 @@ namespace Engine {
|
||||
void SetMoveSpeed(f32 speed) { m_MoveSpeed = speed; }
|
||||
void SetMouseSensitivity(f32 sens) { m_MouseSensitivity = sens; }
|
||||
|
||||
// 鼠标视角总开关(默认开)。交互 = 按住右键自由视角(光标捕获),
|
||||
// 松开释放光标;右键落在 ImGui 面板上时归 UI 不触发相机
|
||||
// 相机输入总开关(默认开)。关闭后转向/环绕/推拉/飞行全部静止
|
||||
void SetMouseLookEnabled(const bool enabled) { m_MouseLookEnabled = enabled; }
|
||||
bool IsMouseLookEnabled() const { return m_MouseLookEnabled; }
|
||||
|
||||
@@ -44,6 +58,12 @@ namespace Engine {
|
||||
f32 m_MoveSpeed = 2.5f;
|
||||
f32 m_MouseSensitivity = 0.1f;
|
||||
bool m_MouseLookEnabled = true;
|
||||
|
||||
// 焦点环绕状态:pivot + 距离。首次环绕无 pivot 时自动取当前
|
||||
// 视线上 m_OrbitDistance 处;FocusOn 显式设置
|
||||
glm::vec3 m_OrbitPivot{0.0f};
|
||||
f32 m_OrbitDistance = 5.0f;
|
||||
bool m_HasPivot = false;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
Reference in New Issue
Block a user