新增调试绘制体系:DebugDraw 服务 + 物理调试 pass + 脚本侧力学线
通用图元(线/箭头四翼头/球/胶囊/盒)瞬时+持久双缓冲聚合; 物理 pass 画刚体速度/重力/接触反力;角色 collider 与力学 线归位(引擎只画资产、脚本画行为);线宽按设备上限钳制
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// DebugDraw:引擎级通用调试图元服务(Unity Debug.DrawLine / UE
|
||||
// DrawDebugHelpers 的对应物)。
|
||||
//
|
||||
// 分层定位:全局静态 API,任何层(脚本/物理/动画/AI)调用即收集;
|
||||
// Renderer 每帧取走缓冲,PhysicsDebugPass 统一上传叠加渲染。引擎侧
|
||||
// 只写这一次,之后一切新可视化 = 调用方加几行,不再碰引擎代码。
|
||||
//
|
||||
// 语义对齐 Unity/UE:
|
||||
// duration <= 0 → 只画当前帧(调用方每帧重调,Unity DrawLine 同)
|
||||
// duration > 0 → 存活 duration 秒(内部持久列表,期间无需重调;
|
||||
// 固定步长系统用 2×步长 即可跨渲染帧无缝续接)
|
||||
// depthTest=false → 透视遮挡直显(UE DrawDebugLine bPersistent 位)
|
||||
// width → 线宽(需 wideLines 特性,设备不支持时钳回 1.0)
|
||||
//
|
||||
// 线程模型:主线程单写单读(脚本 OnUpdate 收集 → Renderer 上传 →
|
||||
// EndFrame 翻页)。
|
||||
// 预算:kMaxVerts 截断 + 一次告警(调试图元打满是滥用信号)。
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_DEBUGDRAW_H
|
||||
#define HELLOVULKAN_DEBUGDRAW_H
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Engine::Debug {
|
||||
|
||||
// 顶点(28B):与 PhysicsDebugVertex 同布局——渲染 pass 复用同一
|
||||
// 顶点输入态(pos vec3 + color vec4)
|
||||
struct Vertex {
|
||||
glm::vec3 pos;
|
||||
glm::vec4 color;
|
||||
};
|
||||
|
||||
// 渲染批次:同 (拓扑, 线宽, 深度测试) 的连续顶点段。调用方按
|
||||
// 参数自动分组,draw 侧每批一次状态切换(动态状态零管线对象)
|
||||
struct Batch {
|
||||
bool tris; // true = triangleList / false = lineList
|
||||
f32 width;
|
||||
bool depthTest;
|
||||
u32 first; // 顶点偏移(顶点数,非字节)
|
||||
u32 count;
|
||||
};
|
||||
|
||||
// 单帧收集结果(Renderer 每帧消费,勿手动修改)
|
||||
struct DebugFrame {
|
||||
std::vector<Vertex> verts;
|
||||
std::vector<Batch> batches;
|
||||
|
||||
void Clear() { verts.clear(); batches.clear(); }
|
||||
bool Empty() const { return batches.empty(); }
|
||||
};
|
||||
|
||||
// 顶点预算(每渲染帧):调试线框足够用,溢出截断 + 告警一次
|
||||
inline constexpr u32 kMaxVerts = 1 << 16;
|
||||
|
||||
// ---- 全局开关 ----
|
||||
void SetEnabled(bool on);
|
||||
bool IsEnabled();
|
||||
void Clear(); // 清空瞬时 + 持久图元(PIE 停止/场景切换时调用)
|
||||
|
||||
// ---- 线类(全部世界空间)----
|
||||
void Line(const glm::vec3& a, const glm::vec3& b,
|
||||
const glm::vec4& color,
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// Ray:from 出发沿单位方向 dirNorm 画 length 长(Unity DrawRay 同形)
|
||||
void Ray(const glm::vec3& from, const glm::vec3& dirNorm, f32 length,
|
||||
const glm::vec4& color,
|
||||
f32 width = 1.0f, f32 duration = 0.0f, bool depthTest = true);
|
||||
|
||||
// 箭头:主干 + 两翼头(正交基自动构建,零向量方向安全退化成点)
|
||||
void Arrow(const glm::vec3& from, const glm::vec3& to,
|
||||
const glm::vec4& color, f32 headSize = 0.12f,
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// 十字标记(Unity Debug.DrawCross 同位)
|
||||
void Cross(const glm::vec3& pos, f32 size, const glm::vec4& color,
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// ---- 形状线框 ----
|
||||
|
||||
// 三大圆经线圈(UE DrawDebugSphere 同形)
|
||||
void WireSphere(const glm::vec3& center, f32 radius,
|
||||
const glm::vec4& color, int segments = 16,
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// 朝向 normal 的平面圆
|
||||
void WireCircle(const glm::vec3& center, f32 radius,
|
||||
const glm::vec3& normal, const glm::vec4& color,
|
||||
int segments = 24,
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// 轴对齐 / 旋转盒(rot 单位四元数 = AABB;UE DrawDebugBox 同形)
|
||||
void WireBox(const glm::vec3& center, const glm::vec3& halfExtents,
|
||||
const glm::vec4& color,
|
||||
const glm::quat& rot = glm::quat(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// 胶囊线框:轴向 local +Y(Jolt 惯例),halfHeight = 圆柱段半长
|
||||
//(总高 = 2×(halfHeight+radius),与引擎 CharacterController 参数一致)
|
||||
void WireCapsule(const glm::vec3& center, f32 radius, f32 halfHeight,
|
||||
const glm::vec4& color,
|
||||
const glm::quat& rot = glm::quat(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
f32 width = 1.0f, f32 duration = 0.0f,
|
||||
bool depthTest = true);
|
||||
|
||||
// ---- 便捷色:0xRRGGBB → 线性 HDR vec4(可 >1 过 tonemap 依旧醒目)----
|
||||
constexpr glm::vec4 Rgb(u32 hex, f32 alpha = 1.0f)
|
||||
{
|
||||
constexpr f32 kInv = 1.0f / 255.0f;
|
||||
return {(static_cast<f32>((hex >> 16) & 0xFF)) * kInv,
|
||||
(static_cast<f32>((hex >> 8) & 0xFF)) * kInv,
|
||||
(static_cast<f32>(hex & 0xFF)) * kInv,
|
||||
alpha};
|
||||
}
|
||||
|
||||
// ---- Renderer 消费端(业务代码勿调用)----
|
||||
|
||||
// 取当前帧缓冲(禁用/空 = Empty)。Renderer 上传窗口调用
|
||||
const DebugFrame& Frame();
|
||||
|
||||
// 翻页:清瞬时缓冲 + 清过期持久项。Renderer 上传完成后调用
|
||||
void EndFrame();
|
||||
|
||||
} // namespace Engine::Debug
|
||||
|
||||
#endif //HELLOVULKAN_DEBUGDRAW_H
|
||||
Reference in New Issue
Block a user