MeshFactory:程序化几何单一源 + CreatePrimitive 链路
新增 MeshFactory(Cube/Plane/Sphere/Cylinder/Cone/Torus + 切线计算), Model 程序化几何改走 MeshFactory(收敛为单一几何源,消除重复的顶点 生成),并新增 CreatePrimitive;打通 AssetManager/IAssetUploader/ VulkanAssetUploader 的 CreatePrimitive 链路;编辑器 Procedural 弹窗 下拉 + ResolveProcedural 伪路径反解 + 场景序列化(程序化图元可存取)。
This commit is contained in:
@@ -805,8 +805,8 @@ void Model::InitDefaultTextures()
|
||||
Model::Model(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
ProceduralTag, f32 halfSize, const std::array<u8, 4>& rgba,
|
||||
bool transparent)
|
||||
ProceduralTag, MeshData&& geo, const std::array<u8, 4>& rgba,
|
||||
bool transparent, const std::string& name)
|
||||
: m_Device(device)
|
||||
, m_Allocator(allocator)
|
||||
, m_DescriptorManager(descriptorManager)
|
||||
@@ -825,16 +825,9 @@ Model::Model(Device& device, MemoryAllocator& allocator,
|
||||
std::to_string(rgba[3]);
|
||||
m_TextureCache.emplace(texKey, std::move(tex));
|
||||
|
||||
// XZ 平面,法线 +Y,从上往下看 CCW 绕序
|
||||
const f32 h = halfSize;
|
||||
std::vector<Vertex> vertices = {
|
||||
{{-h, 0.0f, -h}, {0, 1, 0}, {0.0f, 0.0f}},
|
||||
{{-h, 0.0f, h}, {0, 1, 0}, {0.0f, 0.0f}},
|
||||
{{ h, 0.0f, h}, {0, 1, 0}, {0.0f, 0.0f}},
|
||||
{{ h, 0.0f, -h}, {0, 1, 0}, {0.0f, 0.0f}},
|
||||
};
|
||||
const std::vector<u32> indices = {0, 1, 2, 0, 2, 3};
|
||||
const std::vector<std::vector<u32>> lodIndices = {indices};
|
||||
// 几何(顶点/索引 + 逐顶点切线)由 MeshFactory 产出:单一几何源,
|
||||
// 各具名工厂不再各自内联一套立方体/平面
|
||||
const std::vector<std::vector<u32>> lodIndices = {std::move(geo.indices)};
|
||||
|
||||
// 材质/纹理生命周期随模型(缓存持有);颜色纹理必须显式覆盖 albedo
|
||||
// 槽——缺了会折到默认白纹理(白板叠白地 → 平面“消失”的教训)
|
||||
@@ -845,11 +838,9 @@ Model::Model(Device& device, MemoryAllocator& allocator,
|
||||
overrides);
|
||||
|
||||
m_Meshes.push_back(CreateScope<Mesh>(
|
||||
m_Device, m_Allocator, vertices, lodIndices, mat));
|
||||
// 程序化平面同样登记内建材质快照(与 m_Meshes 下标对齐,
|
||||
// 编辑器材质槽 UI 不越界)
|
||||
m_MeshMaterialInfos.push_back(
|
||||
{"Plane", {}, MaterialParams{}, transparent});
|
||||
m_Device, m_Allocator, geo.vertices, lodIndices, mat));
|
||||
// 内建材质快照(与 m_Meshes 下标对齐,编辑器材质槽 UI 不越界)
|
||||
m_MeshMaterialInfos.push_back({name, {}, MaterialParams{}, transparent});
|
||||
RebuildUnionBounds();
|
||||
}
|
||||
|
||||
@@ -860,8 +851,9 @@ Scope<Model> Model::CreatePlane(Device& device, MemoryAllocator& allocator,
|
||||
{
|
||||
return Scope<Model>(new Model(device, allocator, descriptorManager,
|
||||
textureLayout, ProceduralTag{},
|
||||
halfSize, std::array<u8, 4>{r, g, b, 255},
|
||||
false));
|
||||
MeshFactory::Plane(halfSize),
|
||||
std::array<u8, 4>{r, g, b, 255}, false,
|
||||
"Plane"));
|
||||
}
|
||||
|
||||
Scope<Model> Model::CreateTransparentPlane(
|
||||
@@ -872,8 +864,9 @@ Scope<Model> Model::CreateTransparentPlane(
|
||||
{
|
||||
return Scope<Model>(new Model(device, allocator, descriptorManager,
|
||||
textureLayout, ProceduralTag{},
|
||||
halfSize, std::array<u8, 4>{r, g, b, a},
|
||||
true));
|
||||
MeshFactory::Plane(halfSize),
|
||||
std::array<u8, 4>{r, g, b, a}, true,
|
||||
"Plane"));
|
||||
}
|
||||
|
||||
Scope<Model> Model::CreateCube(Device& device, MemoryAllocator& allocator,
|
||||
@@ -882,81 +875,36 @@ Scope<Model> Model::CreateCube(Device& device, MemoryAllocator& allocator,
|
||||
f32 halfSize, u8 r, u8 g, u8 b)
|
||||
{
|
||||
return Scope<Model>(new Model(device, allocator, descriptorManager,
|
||||
textureLayout, CubeTag{},
|
||||
halfSize, std::array<u8, 4>{r, g, b, 255}));
|
||||
textureLayout, ProceduralTag{},
|
||||
MeshFactory::Cube(halfSize),
|
||||
std::array<u8, 4>{r, g, b, 255}, false,
|
||||
"Cube"));
|
||||
}
|
||||
|
||||
// 程序化立方体:6 面 24 顶点(面法线朝外,CCW 从外看),36 索引。
|
||||
// 结构镜像平面 ctor:默认纹理 → 纯色 albedo 覆盖 → 单 mesh
|
||||
Model::Model(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
CubeTag, f32 halfSize, const std::array<u8, 4>& rgba)
|
||||
: m_Device(device)
|
||||
, m_Allocator(allocator)
|
||||
, m_DescriptorManager(descriptorManager)
|
||||
, m_TextureLayout(textureLayout)
|
||||
// 通用程序化图元:形状名 → MeshFactory 几何。非法形状名/空几何返回
|
||||
// nullptr(调用方回退,绝不把空 mesh 塞进 Mesh)
|
||||
Scope<Model> Model::CreatePrimitive(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
const std::string& shape,
|
||||
const PrimitiveDesc& desc,
|
||||
u8 r, u8 g, u8 b)
|
||||
{
|
||||
// 纯色贴图直供 albedo 槽;生命周期挂进纹理缓存(键含 rgba 值,
|
||||
// 同色共享、异色互不冲突)——与平面 ctor 同一套
|
||||
InitDefaultTextures();
|
||||
Scope<Texture> tex = Texture::CreateSolidColor(device, allocator,
|
||||
rgba[0], rgba[1], rgba[2]);
|
||||
Texture* albedoOverride = tex.get();
|
||||
const std::string texKey = "proc-cube:" + std::to_string(rgba[0]) + ',' +
|
||||
std::to_string(rgba[1]) + ',' + std::to_string(rgba[2]) + ',' +
|
||||
std::to_string(rgba[3]);
|
||||
m_TextureCache.emplace(texKey, std::move(tex));
|
||||
if (!MeshFactory::IsKnownShape(shape)) return nullptr;
|
||||
MeshData geo = MeshFactory::Make(shape, desc);
|
||||
if (geo.vertices.empty() || geo.indices.empty()) return nullptr;
|
||||
|
||||
const f32 h = halfSize;
|
||||
// 逐面 4 顶点(底左/底右/顶右/顶左,从面外看)+ 单位 UV
|
||||
const glm::vec3 P[24] = {
|
||||
// +Z(前)
|
||||
{-h,-h, h}, { h,-h, h}, { h, h, h}, {-h, h, h},
|
||||
// -Z(后)
|
||||
{ h,-h,-h}, {-h,-h,-h}, {-h, h,-h}, { h, h,-h},
|
||||
// +Y(上)
|
||||
{-h, h, h}, { h, h, h}, { h, h,-h}, {-h, h,-h},
|
||||
// -Y(下)
|
||||
{-h,-h,-h}, { h,-h,-h}, { h,-h, h}, {-h,-h, h},
|
||||
// +X(右)
|
||||
{ h,-h, h}, { h,-h,-h}, { h, h,-h}, { h, h, h},
|
||||
// -X(左)
|
||||
{-h,-h,-h}, {-h,-h, h}, {-h, h, h}, {-h, h,-h},
|
||||
};
|
||||
const glm::vec3 N[6] = {
|
||||
{0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0},
|
||||
};
|
||||
const glm::vec2 UV[4] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
vertices.reserve(24);
|
||||
for (u32 f = 0; f < 6; ++f) {
|
||||
for (u32 i = 0; i < 4; ++i) {
|
||||
vertices.push_back({P[f * 4 + i], N[f], UV[i]});
|
||||
}
|
||||
// 显示名 = 形状名首字母大写(编辑器材质槽显示用)
|
||||
std::string name = shape;
|
||||
if (!name.empty()) {
|
||||
name[0] = static_cast<char>(std::toupper(
|
||||
static_cast<unsigned char>(name[0])));
|
||||
}
|
||||
std::vector<u32> indices;
|
||||
indices.reserve(36);
|
||||
for (u32 f = 0; f < 6; ++f) {
|
||||
const u32 b = f * 4;
|
||||
const std::vector<u32> quad = {b, b + 1, b + 2, b, b + 2, b + 3};
|
||||
indices.insert(indices.end(), quad.begin(), quad.end());
|
||||
}
|
||||
const std::vector<std::vector<u32>> lodIndices = {indices};
|
||||
|
||||
std::string paths[Material::kSlotCount] = {"", "", "", ""};
|
||||
std::array<Texture*, Material::kSlotCount> overrides{};
|
||||
overrides[Material::Albedo] = albedoOverride;
|
||||
Material* mat = GetOrCreateMaterial(paths, MaterialParams{}, false,
|
||||
overrides);
|
||||
|
||||
m_Meshes.push_back(CreateScope<Mesh>(
|
||||
m_Device, m_Allocator, vertices, lodIndices, mat));
|
||||
// 内建材质快照(与 m_Meshes 下标对齐,编辑器材质槽 UI 不越界)
|
||||
m_MeshMaterialInfos.push_back(
|
||||
{"Cube", {}, MaterialParams{}, false});
|
||||
RebuildUnionBounds();
|
||||
return Scope<Model>(new Model(device, allocator, descriptorManager,
|
||||
textureLayout, ProceduralTag{},
|
||||
std::move(geo),
|
||||
std::array<u8, 4>{r, g, b, 255}, false,
|
||||
name));
|
||||
}
|
||||
|
||||
// 资产显示名:文件 stem;无信息量(空 / 导入资产库的 "asset")时读
|
||||
|
||||
Reference in New Issue
Block a user