MeshFactory:程序化几何单一源 + CreatePrimitive 链路
新增 MeshFactory(Cube/Plane/Sphere/Cylinder/Cone/Torus + 切线计算), Model 程序化几何改走 MeshFactory(收敛为单一几何源,消除重复的顶点 生成),并新增 CreatePrimitive;打通 AssetManager/IAssetUploader/ VulkanAssetUploader 的 CreatePrimitive 链路;编辑器 Procedural 弹窗 下拉 + ResolveProcedural 伪路径反解 + 场景序列化(程序化图元可存取)。
This commit is contained in:
@@ -229,6 +229,12 @@ namespace Engine
|
||||
// 尺寸变化走实体 Transform 缩放,勿按尺寸炸缓存
|
||||
ModelRef CreateCube(f32 halfSize, u8 r, u8 g, u8 b);
|
||||
|
||||
// 通用程序化图元(MeshFactory 形状名 + 参数):同形状同参数同色
|
||||
// 缓存去重。几何唯一源 = MeshFactory(见 MeshFactory.h)
|
||||
ModelRef CreatePrimitive(const std::string& shape,
|
||||
const PrimitiveDesc& desc,
|
||||
u8 r, u8 g, u8 b);
|
||||
|
||||
// 环境资产(HDR → IBL 预积分四件套)。路径缓存去重,
|
||||
// 重复 Load 同一路径零成本(动态切换场景直接反复调用)
|
||||
EnvRef LoadEnvironment(const std::string& path);
|
||||
|
||||
@@ -45,6 +45,12 @@ namespace Engine::Assets {
|
||||
// 程序化纯色立方体(halfSize 为半边长;占位几何/碎片模拟)
|
||||
virtual Scope<Model> CreateCube(f32 halfSize, u8 r, u8 g, u8 b) = 0;
|
||||
|
||||
// 通用程序化图元(MeshFactory 形状名:cube/plane/sphere/cylinder/
|
||||
// cone/torus 等):形状 + 参数 → 单 mesh 模型。非法形状返回 nullptr
|
||||
virtual Scope<Model> CreatePrimitive(const std::string& shape,
|
||||
const PrimitiveDesc& desc,
|
||||
u8 r, u8 g, u8 b) = 0;
|
||||
|
||||
// 环境 HDR → IBL 预积分四件套(compute 生成,毫秒级;失败返回 nullptr)
|
||||
virtual Scope<Cubemap> LoadEnvironment(const std::string& path) = 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/10/18.
|
||||
//
|
||||
// MeshFactory:预制图元的 CPU 几何生成端(唯一几何源)。
|
||||
//
|
||||
// 定位对齐 UE 的 Engine\Source\Runtime\Engine\...(内置基础网格)思路:
|
||||
// 引擎只保留一套"参数化图元 → 顶点/索引"的生成器,程序化 Model、
|
||||
// 物理形状、脚本与编辑器下拉全部复用它,避免各路径各写一份立方体。
|
||||
//
|
||||
// 契约:
|
||||
// - 所有图元中心在局部原点(平面在 y=0 的 XZ 面),尺寸为世界单位,
|
||||
// 尺寸变化统一走实体 Transform 缩放,不按尺寸炸资产缓存;
|
||||
// - 面法线朝外、CCW 从外正视,可被背面剔除;
|
||||
// - 切线已按 UV 正交化(法线贴图 TBN 可用),退化为任一与 N 正交向量;
|
||||
// - 输出 LOD0 单级索引(图元顶点少,无简化链价值)。
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_MESHFACTORY_H
|
||||
#define HELLOVULKAN_MESHFACTORY_H
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <Engine/Renderer/Vertex.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
// 图元参数(形状无关的标量集):各形状只读取自己关心的字段。
|
||||
// 默认值给"半径/半边长 0.5、高 1"的规格化尺寸,贴合单位立方体约定。
|
||||
struct PrimitiveDesc {
|
||||
f32 size = 0.5f; // 半边长(cube/plane)/ 半径(sphere/cylinder/cone)
|
||||
f32 height = 1.0f; // 圆柱/圆锥高(沿 +Y,几何中心在原点)
|
||||
f32 majorRadius = 0.5f; // 圆环主半径
|
||||
f32 minorRadius = 0.15f; // 圆环管半径
|
||||
u32 segments = 32; // 环绕细分(球/柱/锥/圆环主环)
|
||||
u32 rings = 16; // 纵向细分(球)/ 圆环管环细分
|
||||
u32 subdivisions = 1; // 平面每轴网格细分
|
||||
};
|
||||
|
||||
// 预制图元的 CPU 几何(渲染 Mesh 与物理/脚本共用)。
|
||||
struct MeshData {
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<u32> indices; // LOD0(三角形列表)
|
||||
};
|
||||
|
||||
class MeshFactory {
|
||||
public:
|
||||
// 按名字取形状(ShapeNames 中任一);未知名字返回空 MeshData。
|
||||
static MeshData Make(const std::string& shape, const PrimitiveDesc& desc);
|
||||
|
||||
// ---- 具名构造(编辑器下拉 / 物理形状 / 脚本可直接调用)----
|
||||
static MeshData Cube(f32 halfSize);
|
||||
static MeshData Plane(f32 halfSize, u32 subdivisions = 1);
|
||||
static MeshData Sphere(f32 radius, u32 segments = 32, u32 rings = 16);
|
||||
static MeshData Cylinder(f32 radius, f32 height, u32 segments = 32);
|
||||
static MeshData Cone(f32 radius, f32 height, u32 segments = 32);
|
||||
static MeshData Torus(f32 majorRadius, f32 minorRadius,
|
||||
u32 majorSegments = 32, u32 minorSegments = 16);
|
||||
|
||||
// 已知图元名(UI 下拉 / 伪路径校验的唯一定义点)
|
||||
static const std::vector<std::string>& ShapeNames();
|
||||
static bool IsKnownShape(const std::string& shape);
|
||||
|
||||
private:
|
||||
// 逐三角面积加权累积切线 → 对 N 正交化 → 归一(退化取正交兜底)
|
||||
static void ComputeTangents(MeshData& mesh);
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_MESHFACTORY_H
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <Engine/Renderer/Material.h>
|
||||
#include <Engine/Renderer/Mesh.h>
|
||||
#include <Engine/Renderer/MeshFactory.h> // 程序化几何唯一源(MeshData/PrimitiveDesc)
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <assimp/matrix4x4.h> // 默认参数需完整类型(烘焙节点变换用)
|
||||
@@ -150,9 +151,12 @@ namespace Engine
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
ParsedModel&& parsed);
|
||||
|
||||
// 程序化模型:单位法线朝上的 XZ 平面(纯色贴图),用于地面等。
|
||||
// size 为半边长(平面总边长 = 2*size)。
|
||||
// 程序化几何标签:几何统一来自 MeshFactory(单一几何源),
|
||||
// 本类只负责把几何 + 纯色 albedo 组装成可渲染 Model
|
||||
struct ProceduralTag {};
|
||||
|
||||
// 程序化纯色平面:单位法线朝上的 XZ 平面(纯色贴图),用于地面等。
|
||||
// size 为半边长(平面总边长 = 2*size)。
|
||||
static Scope<Model> CreatePlane(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
@@ -164,15 +168,25 @@ namespace Engine
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
f32 halfSize, u8 r, u8 g, u8 b, u8 a);
|
||||
|
||||
// 程序化立方体(6 面 24 顶点纯色贴图,halfSize = 半边长):
|
||||
// 程序化立方体(halfSize = 半边长,几何走 MeshFactory::Cube):
|
||||
// 通用占位几何(碎片模拟的墙/块等)。尺寸变化走实体 Transform
|
||||
// 缩放——同 halfSize 同色共享一份缓存模型
|
||||
struct CubeTag {};
|
||||
static Scope<Model> CreateCube(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
f32 halfSize, u8 r, u8 g, u8 b);
|
||||
|
||||
// 通用程序化图元(MeshFactory 形状名:cube/plane/sphere/cylinder/
|
||||
// cone/torus 等):几何由 MeshFactory::Make 生成,纯色 albedo。
|
||||
// 非法形状名返回 nullptr(调用方回退)
|
||||
static Scope<Model> CreatePrimitive(Device& device,
|
||||
MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
const std::string& shape,
|
||||
const PrimitiveDesc& desc,
|
||||
u8 r, u8 g, u8 b);
|
||||
|
||||
~Model();
|
||||
|
||||
Model(const Model&) = delete;
|
||||
@@ -218,18 +232,14 @@ namespace Engine
|
||||
const std::vector<ModelBone>& GetBones() const { return m_Bones; }
|
||||
|
||||
private:
|
||||
// 程序化几何骨架:只建默认纹理 + 纯色 albedo 覆盖,mesh 顶点/索引
|
||||
// 由 MeshFactory 产出(见 .cpp)。name = 编辑器材质槽显示名。
|
||||
// 各具名工厂(CreatePlane/Cube/Primitive)都折到这一个 ctor
|
||||
Model(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
ProceduralTag, f32 halfSize, const std::array<u8, 4>& rgba,
|
||||
bool transparent);
|
||||
|
||||
// 程序化立方体骨架:只建默认纹理 + 纯色 albedo 覆盖,mesh 由
|
||||
// 立方体路径填(6 面,顶点法线朝外)
|
||||
Model(Device& device, MemoryAllocator& allocator,
|
||||
DescriptorManager& descriptorManager,
|
||||
vk::DescriptorSetLayout textureLayout,
|
||||
CubeTag, f32 halfSize, const std::array<u8, 4>& rgba);
|
||||
ProceduralTag, MeshData&& geo, const std::array<u8, 4>& rgba,
|
||||
bool transparent, const std::string& name);
|
||||
|
||||
// 空模型骨架(FromParsed 用):只建默认纹理,mesh 由调用方填
|
||||
Model(Device& device, MemoryAllocator& allocator,
|
||||
|
||||
@@ -38,6 +38,9 @@ namespace Engine {
|
||||
Scope<Model> CreateTransparentPlane(f32 halfSize,
|
||||
u8 r, u8 g, u8 b, u8 a) override;
|
||||
Scope<Model> CreateCube(f32 halfSize, u8 r, u8 g, u8 b) override;
|
||||
Scope<Model> CreatePrimitive(const std::string& shape,
|
||||
const PrimitiveDesc& desc,
|
||||
u8 r, u8 g, u8 b) override;
|
||||
Scope<Cubemap> LoadEnvironment(const std::string& path) override;
|
||||
Scope<Cubemap> LoadEnvironment(const std::string& path,
|
||||
DecodedEquirect&& decoded) override;
|
||||
|
||||
Reference in New Issue
Block a user