refactor: Camera 位姿统一到 TransformComponent(单一事实源)

- Camera 删除内部 position/yaw/pitch 状态:Update 把鼠标旋转与 WASD
  移动直接写回实体 Transform(rotation.y=yaw / rotation.x=pitch,
  移动基向量由实体旋转推导,有变更才 Compose)
- GetView(transform) = 实体世界矩阵的逆——相机即实体,视图矩阵无
  第二来源;Scene::GetPrimaryCamera 可选带出实体 Transform
- 默认朝向约定变化:rotation.y=0 = 看向 -Z(与旧 yaw=-90 等价)
- 消除 CameraComponent 位置与 Transform 脱节的遗留债
This commit is contained in:
2026-09-23 15:14:29 +08:00
parent 019c17c7e7
commit 1bc44e261b
6 changed files with 71 additions and 67 deletions
+4 -2
View File
@@ -86,8 +86,10 @@ namespace Engine::ECS {
// ---- 常用查询 ----
// primary 相机(渲染视角来源);无则返回 nullptr
CameraComponent* GetPrimaryCamera();
// 主相机(primary=true,渲染视角来源);无则返回 nullptr。
// outTransform 可选:带出该实体的 TransformComponent
//(相机位姿的单一事实源)
CameraComponent* GetPrimaryCamera(TransformComponent** outTransform = nullptr);
private:
Registry m_Registry;
+11 -27
View File
@@ -2,8 +2,11 @@
// Created by atdunbg on 2026/9/22.
//
// Camera:独立的相机模块。
// 职责:输入驱动的运动更新 + 视图/投影矩阵计算。
// 不再依赖具体渲染器——Renderer/RenderGraph 只消费它的矩阵输出。
//
// 设计(Transform 单一事实源):相机的位置与朝向完全由实体上的
// TransformComponent 承载——Update 把输入直接写回 transform(末尾
// Compose),视图矩阵 = 实体世界矩阵的逆(本地 -Z 为视线方向)。
// 相机类自身不保存任何位姿状态,杜绝"位置两套来源"的脱节。
//
#ifndef HELLOVULKAN_CAMERA_H
@@ -15,25 +18,20 @@
namespace Engine {
class Window;
namespace ECS { struct TransformComponent; }
class Camera {
public:
// 每帧调用:读取窗口输入,更新位置与朝向
void Update(Window& window, f32 deltaTime);
// 输入驱动:WASD/Space/Shift 移动 + 鼠标视角(需 SetMouseLookEnabled)。
// 全部写回传入的 transform,有变更才 Compose。
void Update(Window& window, ECS::TransformComponent& transform, f32 deltaTime);
glm::mat4 GetView() const;
// 相机视图 = 实体世界矩阵的逆(要求 transform 已 Compose)
glm::mat4 GetView(const ECS::TransformComponent& transform) const;
// Vulkan 投影:内部完成 Y 翻转(clip space Y 向下)和 [0,1] 深度
glm::mat4 GetProjection(f32 aspect, f32 nearZ, f32 farZ) const;
glm::vec3 GetPosition() const { return m_Position; }
void SetPosition(const glm::vec3& pos) { m_Position = pos; }
void SetYaw(f32 yaw) { m_Yaw = yaw; }
void SetPitch(f32 pitch) { m_Pitch = pitch; }
f32 GetYaw() const { return m_Yaw; }
f32 GetPitch() const { return m_Pitch; }
void SetMoveSpeed(f32 speed) { m_MoveSpeed = speed; }
void SetMouseSensitivity(f32 sens) { m_MouseSensitivity = sens; }
@@ -41,24 +39,10 @@ namespace Engine {
void SetMouseLookEnabled(bool enabled) { m_MouseLookEnabled = enabled; }
bool IsMouseLookEnabled() const { return m_MouseLookEnabled; }
glm::vec3 GetForward() const { return m_Forward; }
glm::vec3 GetRight() const { return m_Right; }
glm::vec3 GetUp() const { return m_Up; }
private:
void UpdateBasis();
glm::vec3 m_Position{0.0f, 0.0f, 7.0f};
f32 m_Yaw = -90.0f; // 朝向 -Z
f32 m_Pitch = 0.0f;
f32 m_MoveSpeed = 2.5f;
f32 m_MouseSensitivity = 0.1f;
bool m_MouseLookEnabled = false;
// 缓存的方向基向量,Update 时刷新,避免每帧三角函数重复计算
glm::vec3 m_Forward{0.0f, 0.0f, -1.0f};
glm::vec3 m_Right{1.0f, 0.0f, 0.0f};
glm::vec3 m_Up{0.0f, 1.0f, 0.0f};
};
} // namespace Engine