资产系统侧线第一波:ResolveProcedural 提为公共静态(键格式唯一定义点);Inspector 程序化模型入口;修 Prefab hover 误导性 not loaded;Content Browser 模型拖拽 → Outliner 创建实体
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#define HELLOVULKAN_SCENESERIALIZER_H
|
||||
|
||||
#include <Engine/ECS/Scene.h> // Entity + glm vec3/quat(Prefab API 签名用)
|
||||
#include <Engine/Core/AssetRef.h> // ModelRef(ResolveProcedural 返回值)
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -93,6 +94,13 @@ namespace Engine::Serialization {
|
||||
const std::string& inPath,
|
||||
const glm::vec3* overridePos = nullptr,
|
||||
const glm::quat* overrideRot = nullptr);
|
||||
|
||||
// procedural:// 伪路径 → 参数反解重建(cube/plane/
|
||||
// transparent-plane)。确定性键必然命中缓存;绝不走 assimp。
|
||||
// 未知/格式坏伪路径返回无效句柄。场景加载与编辑器程序化
|
||||
// 入口共用——键格式唯一定义点
|
||||
static ModelRef ResolveProcedural(
|
||||
Assets::AssetManager& assets, const std::string& path);
|
||||
};
|
||||
|
||||
} // namespace Engine::Serialization
|
||||
|
||||
@@ -179,71 +179,17 @@ namespace Engine::Serialization {
|
||||
|
||||
// procedural:// 伪路径 → 参数反解重建(确定性键必然命中缓存;
|
||||
// 绝不对伪路径调 LoadModel——那会走 assimp 必炸)
|
||||
ModelRef ResolveProcedural(Assets::AssetManager& assets,
|
||||
const std::string& path)
|
||||
{
|
||||
constexpr std::string_view kPlane = "procedural://plane/";
|
||||
constexpr std::string_view kTPlane =
|
||||
"procedural://transparent-plane/";
|
||||
constexpr std::string_view kCube = "procedural://cube/";
|
||||
|
||||
if (path.rfind(kCube, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b}"
|
||||
const std::string rest = path.substr(kCube.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[3];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreateCube(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
if (path.rfind(kTPlane, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b},{a}"
|
||||
const std::string rest = path.substr(kTPlane.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[4];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreateTransparentPlane(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]), static_cast<u8>(c[3]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
if (path.rfind(kPlane, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b}"
|
||||
const std::string rest = path.substr(kPlane.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[3];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreatePlane(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
return {}; // 未知伪路径
|
||||
}
|
||||
// 实现见 SceneSerializer::ResolveProcedural(公共静态,编辑器
|
||||
// 程序化入口共用)
|
||||
|
||||
// 模型引用解析降级链:procedural 反解 → GUID 主键 → Path 兜底。
|
||||
// 加载成功后 GetOrCreateGUID 回写注册表(注册表丢档自愈)
|
||||
ModelRef ResolveModel(Assets::AssetManager& assets, u64 guid,
|
||||
const std::string& path)
|
||||
{
|
||||
if (ModelRef ref = ResolveProcedural(assets, path); ref.Valid()) {
|
||||
if (ModelRef ref =
|
||||
SceneSerializer::ResolveProcedural(assets, path);
|
||||
ref.Valid()) {
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -1245,6 +1191,67 @@ namespace Engine::Serialization {
|
||||
}
|
||||
}
|
||||
|
||||
// procedural:// 伪路径 → 参数反解重建(键格式唯一定义点;
|
||||
// 绝不对伪路径调 LoadModel——那会走 assimp 必炸)
|
||||
ModelRef SceneSerializer::ResolveProcedural(
|
||||
Assets::AssetManager& assets, const std::string& path)
|
||||
{
|
||||
constexpr std::string_view kPlane = "procedural://plane/";
|
||||
constexpr std::string_view kTPlane =
|
||||
"procedural://transparent-plane/";
|
||||
constexpr std::string_view kCube = "procedural://cube/";
|
||||
|
||||
if (path.rfind(kCube, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b}"
|
||||
const std::string rest = path.substr(kCube.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[3];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreateCube(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
if (path.rfind(kTPlane, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b},{a}"
|
||||
const std::string rest = path.substr(kTPlane.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[4];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreateTransparentPlane(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]), static_cast<u8>(c[3]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
if (path.rfind(kPlane, 0) == 0) {
|
||||
// "{halfSize}/{r},{g},{b}"
|
||||
const std::string rest = path.substr(kPlane.size());
|
||||
const auto slash = rest.find('/');
|
||||
if (slash == std::string::npos) return {};
|
||||
int c[3];
|
||||
if (!ParseCsvInts(rest.substr(slash + 1), c)) return {};
|
||||
try {
|
||||
return assets.CreatePlane(
|
||||
std::stof(rest.substr(0, slash)),
|
||||
static_cast<u8>(c[0]), static_cast<u8>(c[1]),
|
||||
static_cast<u8>(c[2]));
|
||||
}
|
||||
catch (const std::exception&) { return {}; }
|
||||
}
|
||||
|
||||
return {}; // 未知伪路径
|
||||
}
|
||||
|
||||
ECS::Entity SceneSerializer::InstantiatePrefab(
|
||||
ECS::Scene& scene, Assets::AssetManager& assets,
|
||||
const std::string& inPath,
|
||||
|
||||
Reference in New Issue
Block a user