// // Created by atdunbg on 2026/9/22. // #include #include #include #include #include "GLFW/glfw3.h" namespace Engine { void Camera::Update(Window& window, ECS::TransformComponent& t, f32 deltaTime) { // 鼠标旋转:直接写实体旋转(yaw → rotation.y,pitch → rotation.x) if (m_MouseLookEnabled) { f32 mouseDX = 0, mouseDY = 0; window.GetMouseDelta(mouseDX, mouseDY); if (mouseDX != 0 || mouseDY != 0) { glm::vec3 rot = t.GetRotation(); rot.y += mouseDX * m_MouseSensitivity; rot.x = glm::clamp( rot.x - mouseDY * m_MouseSensitivity, -89.0f, 89.0f); t.SetRotation(rot); } } // 基向量由实体旋转决定(本地 -Z 为视线方向;应用顺序 Y→X, // 与 TransformComponent::Compose 一致;roll 不参与 FPS 相机) const glm::vec3& rot = t.GetRotation(); const glm::mat3 r = static_cast( glm::rotate(glm::mat4(1.0f), glm::radians(rot.y), glm::vec3(0, 1, 0)) * glm::rotate(glm::mat4(1.0f), glm::radians(rot.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)) { t.SetPosition(t.GetPosition() + forward * speed); } if (window.IsKeyPressed(GLFW_KEY_S)) { t.SetPosition(t.GetPosition() - forward * speed); } if (window.IsKeyPressed(GLFW_KEY_A)) { t.SetPosition(t.GetPosition() - right * speed); } if (window.IsKeyPressed(GLFW_KEY_D)) { t.SetPosition(t.GetPosition() + right * speed); } if (window.IsKeyPressed(GLFW_KEY_SPACE)) { t.SetPosition(t.GetPosition() + glm::vec3(0, speed, 0)); } if (window.IsKeyPressed(GLFW_KEY_LEFT_SHIFT)) { t.SetPosition(t.GetPosition() - glm::vec3(0, speed, 0)); } } glm::mat4 Camera::GetView(const ECS::TransformComponent& t) const { // 相机作为实体:视图 = 世界矩阵的逆(无重复位姿状态) return glm::inverse(t.World()); } glm::mat4 Camera::GetProjection(f32 aspect, f32 nearZ, f32 farZ) const { auto proj = glm::perspective(glm::radians(45.0f), aspect, nearZ, farZ); proj[1][1] *= -1.0f; // Vulkan Y 翻转 // Vulkan clip 深度 [0,1]:z' = 0.5*z_clip + 0.5*w_clip。 // perspective 的 w_clip = -z_eye,偏移折算进 z 系数 //(注意:与 ortho 的公式不同,ortho 的 w=1 才能直接加到 [3][2]) proj[2][2] = proj[2][2] * 0.5f - 0.5f; proj[3][2] *= 0.5f; return proj; } } // namespace Engine