feat: Jolt 物理系统——刚体/碰撞体/物理调试图元 + 引擎时间单源

- PhysicsWorld:Jolt 集成,Dynamic/Kinematic/Static 刚体,姿态写回
  Transform(Unity FixedUpdate 语义,吃 scaled dt,暂停自动冻结)
- 碰撞体:Box(默认/手动 halfExtents)+ Mesh 碰撞体(Static→精确
  MeshShape / Dynamic·Kinematic→ConvexHull,数据源 = Mesh ctor 缓存
  的 CPU 位置副本,退化三角剔除,失败回退 Box 并告警)
- PhysicsDebugPass:物理调试图元每帧上传绘制(debug_line shader)
- Time:引擎时间单源(BeginFrame 落定 FrameTime,scaled/unscaled 分离)
- JoltPhysics 以 submodule 接入(官方 url)
This commit is contained in:
2026-10-02 20:08:54 +08:00
parent bfbb18f1a4
commit 1c4b6f37ff
21 changed files with 1589 additions and 31 deletions
@@ -0,0 +1,77 @@
//
// PhysicsDebugPass:物理调试图元叠加(collider 线框/约束/重力/速度/
// 加速度箭头)。
//
// 画在 HDRColor(Forward 之后、TAA 之前):调试图元进入场景主链路——
// TAA 时域累积抗锯齿、Bloom/Tonemap 正常消费,kDebugTransparent 诊断
// 模式下也可见。深度只测不写(被不透明几何正确遮挡),无混合直写
// (fullscreen pass 状态泄漏教训)。
//
// 数据源 = PhysicsWorld 每帧收集的 PhysicsDebugFrame(Application 把
// PhysicsWorld 的帧缓冲指针注入 Renderer)。空帧零绘制;debug 开关
// 全关时 PhysicsWorld 不收集 → 顶点数为 0 → 本 pass 自然零开销。
//
#ifndef HELLOVULKAN_PHYSICSDEBUGPASS_H
#define HELLOVULKAN_PHYSICSDEBUGPASS_H
#include <Engine/Core/Types.h>
#include <Engine/Renderer/Passes/RenderPass.h>
#include <Engine/Renderer/SceneTypes.h>
#include <Engine/Vulkan/UniformBuffer.h>
#include <vulkan/vulkan.hpp>
namespace Engine {
struct PhysicsDebugFrame; // PhysicsDebugTypes.h(Jolt 零依赖契约)
class Device;
class ShaderManager;
class DescriptorManager;
namespace Passes {
class PhysicsDebugPass final : public RenderPass {
public:
// 顶点预算(每帧槽位,按顶点数):物理调试几十个 body 的
// 线框 + 箭头远用不满;溢出截断并告警一次
static constexpr u32 kMaxLineVerts = 1 << 16;
static constexpr u32 kMaxTriVerts = 1 << 16;
PhysicsDebugPass(Device& device, MemoryAllocator& allocator,
ShaderManager& shaders,
DescriptorManager& descriptors,
FrameSceneData& frame,
RG::TextureHandle hdrColor,
RG::TextureHandle depth,
UniformBuffer& lineVB, UniformBuffer& triVB);
~PhysicsDebugPass();
PhysicsDebugPass(const PhysicsDebugPass&) = delete;
PhysicsDebugPass& operator=(const PhysicsDebugPass&) = delete;
void Register(RG::RenderGraph& rg) override;
// 每帧 Renderer::Render 里(该槽位 fence 等待后)上传当帧图元
void PrepareFrame(u32 frameSlot, const PhysicsDebugFrame& src);
private:
Device& m_Device;
DescriptorManager& m_Descriptors;
FrameSceneData& m_Frame;
RG::TextureHandle m_HDRColor;
RG::TextureHandle m_Depth;
UniformBuffer& m_LineVB; // per-slot ring(Renderer 持有生命周期)
UniformBuffer& m_TriVB;
vk::PipelineLayout m_Layout; // 无描述符,push = viewProj 64B
vk::ShaderEXT m_Vert{}, m_Frag{};
std::array<u32, kMaxFramesInFlight> m_LineCounts{};
std::array<u32, kMaxFramesInFlight> m_TriCounts{};
bool m_TruncationWarned = false;
};
} // namespace Passes
} // namespace Engine
#endif //HELLOVULKAN_PHYSICSDEBUGPASS_H