修复编辑器相机与 game 形态黑屏;中文字体与 Q 选择热键
FPS 式视角合成(yaw 世界轴/pitch 本地轴,永不 roll); RMB 自由视角后环绕 pivot 失效待重建(修 Focus 后 MMB/滚轮 瞬移锁回);SceneRenderer 默认 kDisplayDirect(game 形态 Blit 空转+清屏黑屏根因);swapchain 优先 Opaque 合成; ImGui 加载思源黑体(CJK 常用集);Q=纯选择不出杆; 新增 InputMap 动作映射
This commit is contained in:
@@ -40,20 +40,38 @@ namespace Engine {
|
||||
{
|
||||
if (wantLook)
|
||||
{
|
||||
// ---- 6DOF 真自由视角:pitch/yaw 各绕本地轴右乘增量
|
||||
// 四元数(q = q·Δyaw·Δpitch),无欧拉读改写、无
|
||||
// ±89° 钳制——可过顶/翻滚,存储层本就是四元数,
|
||||
// 不存在万向锁。符号沿用旧约定:鼠标右移向右看
|
||||
// (右手系绕 Y 正角向左 → yaw 取负)、鼠标下移
|
||||
// 低头(绕 X 正角抬头 → pitch 取负)----
|
||||
// ---- FPS 式视角(UE/Unity 编辑器视口语义):
|
||||
// yaw 绕世界 up 左乘、pitch 绕本地 X 右乘——
|
||||
// 右轴恒保持水平,水平线永不 roll。此前版本
|
||||
// yaw 也绕本地轴(6DOF 自由视角),俯视后再
|
||||
// 平移鼠标会带 roll,up 向量歪斜。pitch 用
|
||||
// 前向量的仰角钳 ±89°:过顶会倒置视图,编辑
|
||||
// 器视口不要这种行为。符号约定不变:鼠标右移
|
||||
// 向右看、鼠标下移低头 ----
|
||||
const glm::quat dyaw = glm::angleAxis(
|
||||
glm::radians(-mouseDX * m_MouseSensitivity),
|
||||
glm::vec3(0, 1, 0));
|
||||
const glm::quat dpitch = glm::angleAxis(
|
||||
glm::radians(-mouseDY * m_MouseSensitivity),
|
||||
glm::vec3(1, 0, 0));
|
||||
|
||||
const glm::vec3 fwd =
|
||||
transform.GetRotationQuat() * glm::vec3(0, 0, -1);
|
||||
const float pitch =
|
||||
std::asin(glm::clamp(fwd.y, -1.0f, 1.0f));
|
||||
float dPitch = glm::radians(-mouseDY * m_MouseSensitivity);
|
||||
dPitch = glm::clamp(pitch + dPitch,
|
||||
glm::radians(-89.0f),
|
||||
glm::radians(89.0f)) - pitch;
|
||||
const glm::quat dpitch =
|
||||
glm::angleAxis(dPitch, glm::vec3(1, 0, 0));
|
||||
|
||||
transform.SetRotationQuat(
|
||||
transform.GetRotationQuat() * dyaw * dpitch);
|
||||
dyaw * transform.GetRotationQuat() * dpitch);
|
||||
|
||||
// 自由视角改写朝向后,旧环绕 pivot 已不在视线上——
|
||||
// 若保留,下一次 MMB/滚轮会绕老焦点猛拽位置(Focus
|
||||
// 后飞远再 MMB 的"瞬移锁回":角增量 × 大半径 =
|
||||
// 米级甩动)。采 Blender/UE 语义:pivot 跟随当前
|
||||
// 视线,失效待 MMB/滚轮按新视线自动重建
|
||||
m_HasPivot = false;
|
||||
}
|
||||
else if (Input::IsKeyDown(Input::Key::LeftShift))
|
||||
{
|
||||
@@ -116,12 +134,16 @@ namespace Engine {
|
||||
if (wantLook || !flyRequiresRMB)
|
||||
{
|
||||
const f32 speed = m_MoveSpeed * deltaTime;
|
||||
if (Input::IsKeyDown(Input::Key::W)) { transform.SetPosition(transform.GetPosition() + forward * speed); }
|
||||
if (Input::IsKeyDown(Input::Key::S)) { transform.SetPosition(transform.GetPosition() - forward * speed); }
|
||||
if (Input::IsKeyDown(Input::Key::A)) { transform.SetPosition(transform.GetPosition() - right * speed); }
|
||||
if (Input::IsKeyDown(Input::Key::D)) { transform.SetPosition(transform.GetPosition() + right * speed); }
|
||||
if (Input::IsKeyDown(Input::Key::Space)) { transform.SetPosition(transform.GetPosition() + glm::vec3(0, speed, 0)); }
|
||||
if (Input::IsKeyDown(Input::Key::LeftShift)) { transform.SetPosition(transform.GetPosition() - glm::vec3(0, speed, 0)); }
|
||||
bool flew = false;
|
||||
if (Input::IsKeyDown(Input::Key::W)) { transform.SetPosition(transform.GetPosition() + forward * speed); flew = true; }
|
||||
if (Input::IsKeyDown(Input::Key::S)) { transform.SetPosition(transform.GetPosition() - forward * speed); flew = true; }
|
||||
if (Input::IsKeyDown(Input::Key::A)) { transform.SetPosition(transform.GetPosition() - right * speed); flew = true; }
|
||||
if (Input::IsKeyDown(Input::Key::D)) { transform.SetPosition(transform.GetPosition() + right * speed); flew = true; }
|
||||
if (Input::IsKeyDown(Input::Key::Space)) { transform.SetPosition(transform.GetPosition() + glm::vec3(0, speed, 0)); flew = true; }
|
||||
if (Input::IsKeyDown(Input::Key::LeftShift)) { transform.SetPosition(transform.GetPosition() - glm::vec3(0, speed, 0)); flew = true; }
|
||||
// 飞行位移同样令环绕 pivot 失效(同自由视角:位移后老
|
||||
// pivot 与视线脱钩,保留会让 MMB/滚轮绕老焦点拽位置)
|
||||
if (flew) { m_HasPivot = false; }
|
||||
}
|
||||
|
||||
// ---- 滚轮推拉:有 pivot 时改环绕距离(指数步进,近处精细/
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#endif
|
||||
#include <Engine/Renderer/Passes/OutlinePass.h>
|
||||
#include <Engine/Physics/PhysicsDebugTypes.h>
|
||||
#include <Engine/Debug/DebugDraw.h>
|
||||
#include <Engine/Renderer/Cubemap.h>
|
||||
#include <Engine/Renderer/IblGenerator.h>
|
||||
#include <Engine/Renderer/TracyGpuProfiler.h>
|
||||
@@ -114,6 +115,11 @@ namespace Engine
|
||||
u64(Passes::PhysicsDebugPass::kMaxTriVerts) *
|
||||
sizeof(PhysicsDebugVertex),
|
||||
kMaxFramesInFlight, vk::BufferUsageFlagBits::eVertexBuffer);
|
||||
// 通用调试源 ring VB(Engine::Debug 服务;顶点布局与物理源一致)
|
||||
m_DebugLineVB = CreateScope<UniformBuffer>(
|
||||
*m_Device, *m_Allocator,
|
||||
u64(Engine::Debug::kMaxVerts) * sizeof(Engine::Debug::Vertex),
|
||||
kMaxFramesInFlight, vk::BufferUsageFlagBits::eVertexBuffer);
|
||||
#ifdef HELLO_EDITOR
|
||||
// 3.3 Editor gizmo 图元 ring VB(editor 专属;game 构建不分配)。
|
||||
// eVertexBuffer 复用 UniformBuffer 的 per-slot fence 语义,
|
||||
@@ -502,7 +508,8 @@ namespace Engine
|
||||
// TAA 之前)——调试图元进 TAA/Bloom/Tonemap 主链路
|
||||
m_Passes.push_back(CreateScope<Passes::PhysicsDebugPass>(
|
||||
*m_Device, *m_Allocator, *m_ShaderManager, *m_DescriptorManager,
|
||||
frame, m_HDRColor, m_Depth, *m_PhysicsLineVB, *m_PhysicsTriVB));
|
||||
frame, m_HDRColor, m_Depth, *m_PhysicsLineVB, *m_PhysicsTriVB,
|
||||
*m_DebugLineVB));
|
||||
m_PhysicsDebugPass =
|
||||
static_cast<Passes::PhysicsDebugPass*>(m_Passes.back().get());
|
||||
#ifdef HELLO_EDITOR
|
||||
@@ -813,10 +820,16 @@ namespace Engine
|
||||
// MDI 命令/count 同窗口落槽位 ring(fence 已等,写-读竞争关闭)
|
||||
m_SceneGpu->UploadIndirect(frameSlot, frame);
|
||||
|
||||
// 物理调试图元同窗口上传(fence 已等);空帧计数归零,pass 零开销
|
||||
// 物理调试图元同窗口上传(fence 已等);空帧计数归零,pass 零开销。
|
||||
// 通用调试源(Engine::Debug)同窗口取走;EndFrame 翻页(清瞬时 +
|
||||
// 清过期持久项)——即使物理源缺席也必须翻页,防瞬时缓冲累积
|
||||
if (m_PhysicsDebug && m_PhysicsDebugPass) {
|
||||
m_PhysicsDebugPass->PrepareFrame(frameSlot, *m_PhysicsDebug);
|
||||
m_PhysicsDebugPass->PrepareFrame(
|
||||
frameSlot, *m_PhysicsDebug,
|
||||
Engine::Debug::IsEnabled() ? &Engine::Debug::Frame()
|
||||
: nullptr);
|
||||
}
|
||||
Engine::Debug::EndFrame();
|
||||
|
||||
#ifdef HELLO_EDITOR
|
||||
// Editor gizmo 图元同窗口上传(fence 已等);空帧不写,pass 端
|
||||
|
||||
Reference in New Issue
Block a user