MeshFactory:程序化几何单一源 + CreatePrimitive 链路
新增 MeshFactory(Cube/Plane/Sphere/Cylinder/Cone/Torus + 切线计算), Model 程序化几何改走 MeshFactory(收敛为单一几何源,消除重复的顶点 生成),并新增 CreatePrimitive;打通 AssetManager/IAssetUploader/ VulkanAssetUploader 的 CreatePrimitive 链路;编辑器 Procedural 弹窗 下拉 + ResolveProcedural 伪路径反解 + 场景序列化(程序化图元可存取)。
This commit is contained in:
@@ -686,8 +686,13 @@ void InspectorPanel::Draw(const EditorContext& ctx, entt::entity selected)
|
||||
}
|
||||
if (ImGui::BeginPopup("##proc_model"))
|
||||
{
|
||||
static int shape = 0; // 0=cube 1=plane 2=transparent plane
|
||||
static float half = 0.5f;
|
||||
// 形状集合与 MeshFactory::ShapeNames 对齐
|
||||
static int shape = 0; // 0=cube 1=plane 2=tplane
|
||||
// 3=sphere 4=cylinder 5=cone 6=torus
|
||||
static float half = 0.5f; // 半径 / 半边长
|
||||
static float height = 1.0f; // 圆柱 / 圆锥高
|
||||
static float majorR = 0.5f; // 圆环主半径
|
||||
static float minorR = 0.15f; // 圆环管半径
|
||||
static float col[3] = {0.55f, 0.36f, 0.28f};
|
||||
static float alpha = 0.5f;
|
||||
ImGui::RadioButton("Cube", &shape, 0);
|
||||
@@ -695,11 +700,32 @@ void InspectorPanel::Draw(const EditorContext& ctx, entt::entity selected)
|
||||
ImGui::RadioButton("Plane", &shape, 1);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Trans.Plane", &shape, 2);
|
||||
ImGui::RadioButton("Sphere", &shape, 3);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Cylinder", &shape, 4);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Cone", &shape, 5);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Torus", &shape, 6);
|
||||
// 固定宽度而非 -1:弹窗是 AlwaysAutoResize,-1(撑满可用
|
||||
// 宽度)会拿上一帧宽度当基准 → 逐帧膨胀直到撑满屏幕
|
||||
ImGui::SetNextItemWidth(180.0f);
|
||||
ImGui::SliderFloat("half size", &half, 0.01f, 10.0f,
|
||||
"%.2f");
|
||||
ImGui::SliderFloat("size", &half, 0.01f, 10.0f, "%.2f");
|
||||
if (shape == 4 || shape == 5)
|
||||
{
|
||||
ImGui::SetNextItemWidth(180.0f);
|
||||
ImGui::SliderFloat("height", &height, 0.01f, 10.0f,
|
||||
"%.2f");
|
||||
}
|
||||
if (shape == 6)
|
||||
{
|
||||
ImGui::SetNextItemWidth(180.0f);
|
||||
ImGui::SliderFloat("major radius", &majorR, 0.01f, 10.0f,
|
||||
"%.2f");
|
||||
ImGui::SetNextItemWidth(180.0f);
|
||||
ImGui::SliderFloat("minor radius", &minorR, 0.01f, 5.0f,
|
||||
"%.2f");
|
||||
}
|
||||
ImGui::ColorEdit3("color", col);
|
||||
if (shape == 2)
|
||||
{
|
||||
@@ -712,21 +738,37 @@ void InspectorPanel::Draw(const EditorContext& ctx, entt::entity selected)
|
||||
const int r = int(col[0] * 255.0f + 0.5f);
|
||||
const int g = int(col[1] * 255.0f + 0.5f);
|
||||
const int b = int(col[2] * 255.0f + 0.5f);
|
||||
char key[96];
|
||||
if (shape == 2)
|
||||
char key[128];
|
||||
switch (shape)
|
||||
{
|
||||
const int a = int(alpha * 255.0f + 0.5f);
|
||||
case 2:
|
||||
std::snprintf(
|
||||
key, sizeof(key),
|
||||
"procedural://transparent-plane/%.3g/%d,%d,%d,%d",
|
||||
half, r, g, b, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::snprintf(
|
||||
key, sizeof(key),
|
||||
half, r, g, b, int(alpha * 255.0f + 0.5f));
|
||||
break;
|
||||
case 3:
|
||||
std::snprintf(key, sizeof(key),
|
||||
"procedural://sphere/%.3g/%d,%d,%d",
|
||||
half, r, g, b);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
std::snprintf(key, sizeof(key),
|
||||
"procedural://%s/%.3g_%.3g/%d,%d,%d",
|
||||
shape == 4 ? "cylinder" : "cone",
|
||||
half, height, r, g, b);
|
||||
break;
|
||||
case 6:
|
||||
std::snprintf(key, sizeof(key),
|
||||
"procedural://torus/%.3g_%.3g/%d,%d,%d",
|
||||
majorR, minorR, r, g, b);
|
||||
break;
|
||||
default:
|
||||
std::snprintf(key, sizeof(key),
|
||||
"procedural://%s/%.3g/%d,%d,%d",
|
||||
shape == 0 ? "cube" : "plane", half, r, g, b);
|
||||
break;
|
||||
}
|
||||
if (auto ref = Engine::Serialization::
|
||||
SceneSerializer::ResolveProcedural(
|
||||
|
||||
Reference in New Issue
Block a user