Files
HelloVulkan/Engine/src/Renderer/Camera.cpp
T
atdunbg 7d137fa9b1 refactor: Transform 字段封装 + dirty 标记(对齐 UE USceneComponent 真实现)
- 修正上一版"全量暴力重算":UE 实为 dirty 标记 + 惰性计算,前提是
  字段私有(SetRelativeLocation 等 setter 标脏 + 子级传播)
- TransformComponent:SRT 字段私有化,Set/Get/World()/IsDirty 访问器;
  Set* 变更才标脏;AddRotationY 便捷接口
- Scene::UpdateTransforms 只重算脏实体——静止实体零成本;
  层级(父子)传播在脏标记基础上扩展
- 迁移 Camera/SceneRenderer/main.cpp 到封装 API
2026-09-23 15:35:20 +08:00

73 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// Created by atdunbg on 2026/9/22.
//
#include <Engine/Renderer/Camera.h>
#include <Engine/Core/Window.h>
#include <Engine/ECS/Components.h>
#include <glm/gtc/matrix_transform.hpp>
#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::mat3>(
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