feat(editor): Stage 1.1 fully completed - Implement SubAssets metadata generation, JSON disk writing and registry scanning

This commit is contained in:
ayuan9957 2026-05-18 14:24:35 +08:00
parent edf6402a6a
commit bd17aa46ee
9 changed files with 110 additions and 0 deletions

View File

@ -59,6 +59,20 @@ bool MetaCoreWriteMetaJson(
json["package_path"] = metadata.PackagePath.generic_string();
json["source_hash"] = metadata.SourceHash;
// 序列化子资产列表
if (!metadata.SubAssets.empty()) {
auto subAssetsJson = nlohmann::json::array();
for (const auto& subAsset : metadata.SubAssets) {
nlohmann::json subAssetJson;
subAssetJson["guid"] = subAsset.Guid.ToString();
subAssetJson["type"] = subAsset.Type;
subAssetJson["name"] = subAsset.Name;
subAssetJson["index"] = subAsset.Index;
subAssetsJson.push_back(subAssetJson);
}
json["sub_assets"] = subAssetsJson;
}
// 将 JSON 漂亮格式化并写入文件
std::ofstream output(absoluteMetaPath);
if (!output.is_open()) {
@ -102,6 +116,32 @@ bool MetaCoreReadMetaJson(
if (json.contains("source_hash") && json["source_hash"].is_number_integer()) {
outMetadata.SourceHash = json["source_hash"].get<std::uint64_t>();
}
// 解析子资产列表
outMetadata.SubAssets.clear();
if (json.contains("sub_assets") && json["sub_assets"].is_array()) {
for (const auto& subAssetJson : json["sub_assets"]) {
MetaCoreSubAssetMetadata subAsset;
if (subAssetJson.contains("guid") && subAssetJson["guid"].is_string()) {
auto parsed = MetaCoreAssetGuid::Parse(subAssetJson["guid"].get<std::string>());
if (parsed.has_value()) {
subAsset.Guid = *parsed;
}
}
if (subAssetJson.contains("type") && subAssetJson["type"].is_string()) {
subAsset.Type = subAssetJson["type"].get<std::string>();
}
if (subAssetJson.contains("name") && subAssetJson["name"].is_string()) {
subAsset.Name = subAssetJson["name"].get<std::string>();
}
if (subAssetJson.contains("index") && subAssetJson["index"].is_number_integer()) {
subAsset.Index = subAssetJson["index"].get<std::int32_t>();
}
if (subAsset.Guid.IsValid()) {
outMetadata.SubAssets.push_back(subAsset);
}
}
}
return true;
} catch (...) {
return false;
@ -4097,6 +4137,43 @@ bool MetaCoreBuiltinImportPipelineService::ImportSourceFile(const std::filesyste
meshPayloads,
existingModelImportSettings
);
// 收集生成的子资产信息到元数据中,以便落盘和注册表在下次启动时扫描解析
metadata.SubAssets.clear();
for (std::size_t index = 0; index < importedAsset.GeneratedMeshAssets.size(); ++index) {
const auto& mesh = importedAsset.GeneratedMeshAssets[index];
if (mesh.AssetGuid.IsValid()) {
MetaCoreSubAssetMetadata sub;
sub.Guid = mesh.AssetGuid;
sub.Type = "mesh";
sub.Name = mesh.Name;
sub.Index = static_cast<std::int32_t>(index);
metadata.SubAssets.push_back(sub);
}
}
for (std::size_t index = 0; index < importedAsset.GeneratedMaterialAssets.size(); ++index) {
const auto& mat = importedAsset.GeneratedMaterialAssets[index];
if (mat.AssetGuid.IsValid()) {
MetaCoreSubAssetMetadata sub;
sub.Guid = mat.AssetGuid;
sub.Type = "material";
sub.Name = mat.Name;
sub.Index = static_cast<std::int32_t>(index);
metadata.SubAssets.push_back(sub);
}
}
for (std::size_t index = 0; index < importedAsset.GeneratedTextureAssets.size(); ++index) {
const auto& tex = importedAsset.GeneratedTextureAssets[index];
if (tex.AssetGuid.IsValid()) {
MetaCoreSubAssetMetadata sub;
sub.Guid = tex.AssetGuid;
sub.Type = "texture";
sub.Name = tex.Name;
sub.Index = static_cast<std::int32_t>(index);
metadata.SubAssets.push_back(sub);
}
}
importedAssetBytes = MetaCoreSerializeToBytes(importedAsset, registry);
importedAssetTypeName = "MetaCoreModelAssetDocument";

View File

@ -40,6 +40,23 @@ enum class MetaCoreUiVerticalAlignment {
Stretch
};
MC_STRUCT()
struct MetaCoreSubAssetMetadata {
MC_GENERATED_BODY()
MC_PROPERTY()
MetaCoreAssetGuid Guid{};
MC_PROPERTY()
std::string Type{};
MC_PROPERTY()
std::string Name{};
MC_PROPERTY()
std::int32_t Index = 0;
};
MC_STRUCT()
struct MetaCoreAssetMetadataDocument {
MC_GENERATED_BODY()
@ -61,6 +78,9 @@ struct MetaCoreAssetMetadataDocument {
MC_PROPERTY()
std::uint64_t SourceHash = 0;
MC_PROPERTY()
std::vector<MetaCoreSubAssetMetadata> SubAssets{};
};
MC_STRUCT()

View File

@ -42,6 +42,19 @@ void MetaCoreAssetRegistry::ScanDirectory(const std::filesystem::path& rootPath)
// 规格化路径,确保斜杠在跨平台的一致性
std::filesystem::path portablePath(sourcePathStr);
RegisterAsset(*parsedGuid, portablePath);
// 顺便注册该主模型派生的所有子资产(如 mesh, material 等)
if (json.contains("sub_assets") && json["sub_assets"].is_array()) {
for (const auto& subAssetJson : json["sub_assets"]) {
if (subAssetJson.contains("guid") && subAssetJson["guid"].is_string()) {
const std::string subGuidStr = subAssetJson["guid"].get<std::string>();
auto parsedSubGuid = MetaCoreAssetGuid::Parse(subGuidStr);
if (parsedSubGuid.has_value()) {
RegisterAsset(*parsedSubGuid, portablePath);
}
}
}
}
}
}
} catch (...) {