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:
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <Engine/Renderer/Camera.h>
|
||||
#include <Engine/Core/Window.h>
|
||||
#include <Engine/ECS/Components.h>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
@@ -11,9 +12,11 @@
|
||||
|
||||
namespace Engine {
|
||||
|
||||
void Camera::Update(Window& window, f32 deltaTime)
|
||||
void Camera::Update(Window& window, ECS::TransformComponent& t, f32 deltaTime)
|
||||
{
|
||||
// 鼠标旋转(需显式启用,配合 cursor capture 使用)
|
||||
bool dirty = false;
|
||||
|
||||
// 鼠标旋转:直接写实体旋转(yaw → rotation.y,pitch → rotation.x)
|
||||
if (m_MouseLookEnabled)
|
||||
{
|
||||
f32 mouseDX = 0, mouseDY = 0;
|
||||
@@ -21,37 +24,39 @@ namespace Engine {
|
||||
|
||||
if (mouseDX != 0 || mouseDY != 0)
|
||||
{
|
||||
m_Yaw += mouseDX * m_MouseSensitivity;
|
||||
m_Pitch -= mouseDY * m_MouseSensitivity;
|
||||
m_Pitch = glm::clamp(m_Pitch, -89.0f, 89.0f);
|
||||
t.rotation.y += mouseDX * m_MouseSensitivity;
|
||||
t.rotation.x = glm::clamp(
|
||||
t.rotation.x - mouseDY * m_MouseSensitivity, -89.0f, 89.0f);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateBasis();
|
||||
// 基向量由实体旋转决定(本地 -Z 为视线方向;应用顺序 Y→X,
|
||||
// 与 TransformComponent::Compose 一致;roll 不参与 FPS 相机)
|
||||
const glm::mat3 r = static_cast<glm::mat3>(
|
||||
glm::rotate(glm::mat4(1.0f), glm::radians(t.rotation.y),
|
||||
glm::vec3(0, 1, 0)) *
|
||||
glm::rotate(glm::mat4(1.0f), glm::radians(t.rotation.x),
|
||||
glm::vec3(1, 0, 0)));
|
||||
const glm::vec3 forward = r * glm::vec3(0, 0, -1);
|
||||
const glm::vec3 right = r * glm::vec3(1, 0, 0);
|
||||
|
||||
f32 speed = m_MoveSpeed * deltaTime;
|
||||
if (window.IsKeyPressed(GLFW_KEY_W)) m_Position += m_Forward * speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_S)) m_Position -= m_Forward * speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_A)) m_Position -= m_Right * speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_D)) m_Position += m_Right * speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_SPACE)) m_Position.y += speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_LEFT_SHIFT)) m_Position.y -= speed;
|
||||
if (window.IsKeyPressed(GLFW_KEY_W)) { t.position += forward * speed; dirty = true; }
|
||||
if (window.IsKeyPressed(GLFW_KEY_S)) { t.position -= forward * speed; dirty = true; }
|
||||
if (window.IsKeyPressed(GLFW_KEY_A)) { t.position -= right * speed; dirty = true; }
|
||||
if (window.IsKeyPressed(GLFW_KEY_D)) { t.position += right * speed; dirty = true; }
|
||||
if (window.IsKeyPressed(GLFW_KEY_SPACE)) { t.position.y += speed; dirty = true; }
|
||||
if (window.IsKeyPressed(GLFW_KEY_LEFT_SHIFT)) { t.position.y -= speed; dirty = true; }
|
||||
|
||||
// 世界矩阵供 GetView(inverse)与渲染消费
|
||||
if (dirty) t.Compose();
|
||||
}
|
||||
|
||||
void Camera::UpdateBasis()
|
||||
glm::mat4 Camera::GetView(const ECS::TransformComponent& t) const
|
||||
{
|
||||
m_Forward.x = cosf(glm::radians(m_Yaw)) * cosf(glm::radians(m_Pitch));
|
||||
m_Forward.y = sinf(glm::radians(m_Pitch));
|
||||
m_Forward.z = sinf(glm::radians(m_Yaw)) * cosf(glm::radians(m_Pitch));
|
||||
m_Forward = glm::normalize(m_Forward);
|
||||
|
||||
m_Right = glm::normalize(glm::cross(m_Forward, glm::vec3(0, 1, 0)));
|
||||
m_Up = glm::normalize(glm::cross(m_Right, m_Forward));
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetView() const
|
||||
{
|
||||
return glm::lookAt(m_Position, m_Position + m_Forward, m_Up);
|
||||
// 相机作为实体:视图 = 世界矩阵的逆(无重复位姿状态)
|
||||
return glm::inverse(t.world);
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetProjection(f32 aspect, f32 nearZ, f32 farZ) const
|
||||
|
||||
Reference in New Issue
Block a user