807 lines
50 KiB
C++
807 lines
50 KiB
C++
#include "MetaCoreScene/MetaCoreSceneSerializer.h"
|
||
#include "MetaCoreFoundation/MetaCoreReflection.h"
|
||
#include <nlohmann/json.hpp>
|
||
#include <fstream>
|
||
#include <iostream>
|
||
#include <sstream>
|
||
|
||
using json = nlohmann::json;
|
||
|
||
namespace MetaCore {
|
||
|
||
// 辅助方法:将 glm::vec3 序列化为 JSON 数组 [x, y, z]
|
||
static json Vec3ToJson(const glm::vec3& vec) {
|
||
return { vec.x, vec.y, vec.z };
|
||
}
|
||
|
||
// 辅助方法:从 JSON 数组 [x, y, z] 反序列化出 glm::vec3
|
||
static glm::vec3 JsonToVec3(const json& j) {
|
||
if (j.is_array() && j.size() >= 3) {
|
||
return glm::vec3(j[0].get<float>(), j[1].get<float>(), j[2].get<float>());
|
||
}
|
||
return glm::vec3(0.0f);
|
||
}
|
||
|
||
// 辅助方法:将 MetaCoreAssetGuid 转换为 String,方便文本化存储
|
||
static std::string GuidToString(const MetaCoreAssetGuid& guid) {
|
||
return guid.IsValid() ? guid.ToString() : "";
|
||
}
|
||
|
||
// 辅助方法:从 String 反解析为 MetaCoreAssetGuid
|
||
static MetaCoreAssetGuid StringToGuid(const std::string& str) {
|
||
return str.empty() ? MetaCoreAssetGuid{} : MetaCoreAssetGuid::Parse(str).value_or(MetaCoreAssetGuid{});
|
||
}
|
||
|
||
static json SceneEnvironmentToJson(const MetaCoreSceneEnvironmentSettings& environment) {
|
||
json environmentJson = json::object();
|
||
environmentJson["Source"] = static_cast<int>(environment.Source);
|
||
environmentJson["IblKtxPath"] = environment.IblKtxPath.generic_string();
|
||
environmentJson["SkyboxKtxPath"] = environment.SkyboxKtxPath.generic_string();
|
||
environmentJson["SkyboxVisible"] = environment.SkyboxVisible;
|
||
environmentJson["RotationDegrees"] = environment.RotationDegrees;
|
||
environmentJson["IndirectLightIntensity"] = environment.IndirectLightIntensity;
|
||
environmentJson["SkyboxIntensity"] = environment.SkyboxIntensity;
|
||
return environmentJson;
|
||
}
|
||
|
||
static MetaCoreSceneEnvironmentSettings JsonToSceneEnvironment(const json& environmentJson) {
|
||
MetaCoreSceneEnvironmentSettings environment;
|
||
if (!environmentJson.is_object()) {
|
||
return environment;
|
||
}
|
||
if (environmentJson.contains("Source")) environment.Source = static_cast<MetaCoreSceneEnvironmentSource>(environmentJson["Source"].get<int>());
|
||
if (environmentJson.contains("IblKtxPath")) environment.IblKtxPath = environmentJson["IblKtxPath"].get<std::string>();
|
||
if (environmentJson.contains("SkyboxKtxPath")) environment.SkyboxKtxPath = environmentJson["SkyboxKtxPath"].get<std::string>();
|
||
if (environmentJson.contains("SkyboxVisible")) environment.SkyboxVisible = environmentJson["SkyboxVisible"].get<bool>();
|
||
if (environmentJson.contains("RotationDegrees")) environment.RotationDegrees = environmentJson["RotationDegrees"].get<float>();
|
||
if (environmentJson.contains("IndirectLightIntensity")) environment.IndirectLightIntensity = environmentJson["IndirectLightIntensity"].get<float>();
|
||
if (environmentJson.contains("SkyboxIntensity")) environment.SkyboxIntensity = environmentJson["SkyboxIntensity"].get<float>();
|
||
return environment;
|
||
}
|
||
|
||
// 辅助方法:将单个 MetaCoreGameObjectData 转换为 json 格式
|
||
static json GameObjectDataToJson(const MetaCoreGameObjectData& obj, const MetaCoreTypeRegistry& registry) {
|
||
json objJson = json::object();
|
||
const MetaCoreStructDescriptor* objDesc = registry.FindStruct<MetaCoreGameObjectData>();
|
||
if (!objDesc) return objJson;
|
||
|
||
for (const auto& objField : objDesc->Fields) {
|
||
if (objField.Name == "Id") {
|
||
objJson["Id"] = obj.Id;
|
||
} else if (objField.Name == "ParentId") {
|
||
objJson["ParentId"] = obj.ParentId;
|
||
} else if (objField.Name == "Name") {
|
||
objJson["Name"] = obj.Name;
|
||
} else if (objField.Name == "Transform") {
|
||
const MetaCoreStructDescriptor* transDesc = registry.FindStruct<MetaCoreTransformComponent>();
|
||
if (transDesc) {
|
||
json transJson = json::object();
|
||
for (const auto& transField : transDesc->Fields) {
|
||
if (transField.Name == "Position") transJson["Position"] = Vec3ToJson(obj.Transform.Position);
|
||
else if (transField.Name == "RotationEulerDegrees") transJson["RotationEulerDegrees"] = Vec3ToJson(obj.Transform.RotationEulerDegrees);
|
||
else if (transField.Name == "Scale") transJson["Scale"] = Vec3ToJson(obj.Transform.Scale);
|
||
}
|
||
objJson["Transform"] = transJson;
|
||
}
|
||
} else if (objField.Name == "MeshRenderer" && obj.MeshRenderer.has_value()) {
|
||
const MetaCoreStructDescriptor* meshDesc = registry.FindStruct<MetaCoreMeshRendererComponent>();
|
||
if (meshDesc) {
|
||
json meshJson = json::object();
|
||
const auto& mesh = obj.MeshRenderer.value();
|
||
for (const auto& meshField : meshDesc->Fields) {
|
||
if (meshField.Name == "MeshSource") meshJson["MeshSource"] = static_cast<int>(mesh.MeshSource);
|
||
else if (meshField.Name == "BuiltinMesh") meshJson["BuiltinMesh"] = static_cast<int>(mesh.BuiltinMesh);
|
||
else if (meshField.Name == "MeshAssetGuid") meshJson["MeshAssetGuid"] = GuidToString(mesh.MeshAssetGuid);
|
||
else if (meshField.Name == "MaterialAssetGuids") {
|
||
json matGuids = json::array();
|
||
for (const auto& guid : mesh.MaterialAssetGuids) {
|
||
matGuids.push_back(GuidToString(guid));
|
||
}
|
||
meshJson["MaterialAssetGuids"] = matGuids;
|
||
}
|
||
else if (meshField.Name == "SourceModelAssetGuid") meshJson["SourceModelAssetGuid"] = GuidToString(mesh.SourceModelAssetGuid);
|
||
else if (meshField.Name == "SourceModelPath") meshJson["SourceModelPath"] = mesh.SourceModelPath;
|
||
else if (meshField.Name == "SourceNodePath") meshJson["SourceNodePath"] = mesh.SourceNodePath;
|
||
else if (meshField.Name == "BaseColorTextureGuid") meshJson["BaseColorTextureGuid"] = GuidToString(mesh.BaseColorTextureGuid);
|
||
else if (meshField.Name == "MetallicRoughnessTextureGuid") meshJson["MetallicRoughnessTextureGuid"] = GuidToString(mesh.MetallicRoughnessTextureGuid);
|
||
else if (meshField.Name == "NormalTextureGuid") meshJson["NormalTextureGuid"] = GuidToString(mesh.NormalTextureGuid);
|
||
else if (meshField.Name == "EmissiveTextureGuid") meshJson["EmissiveTextureGuid"] = GuidToString(mesh.EmissiveTextureGuid);
|
||
else if (meshField.Name == "AoTextureGuid") meshJson["AoTextureGuid"] = GuidToString(mesh.AoTextureGuid);
|
||
else if (meshField.Name == "BaseColorTexturePath") meshJson["BaseColorTexturePath"] = mesh.BaseColorTexturePath;
|
||
else if (meshField.Name == "MetallicRoughnessTexturePath") meshJson["MetallicRoughnessTexturePath"] = mesh.MetallicRoughnessTexturePath;
|
||
else if (meshField.Name == "NormalTexturePath") meshJson["NormalTexturePath"] = mesh.NormalTexturePath;
|
||
else if (meshField.Name == "EmissiveTexturePath") meshJson["EmissiveTexturePath"] = mesh.EmissiveTexturePath;
|
||
else if (meshField.Name == "AoTexturePath") meshJson["AoTexturePath"] = mesh.AoTexturePath;
|
||
else if (meshField.Name == "DoubleSided") meshJson["DoubleSided"] = mesh.DoubleSided;
|
||
else if (meshField.Name == "Metallic") meshJson["Metallic"] = mesh.Metallic;
|
||
else if (meshField.Name == "Roughness") meshJson["Roughness"] = mesh.Roughness;
|
||
else if (meshField.Name == "AlphaMode") meshJson["AlphaMode"] = static_cast<int>(mesh.AlphaMode);
|
||
else if (meshField.Name == "AlphaCutoff") meshJson["AlphaCutoff"] = mesh.AlphaCutoff;
|
||
else if (meshField.Name == "EmissiveColor") meshJson["EmissiveColor"] = Vec3ToJson(mesh.EmissiveColor);
|
||
else if (meshField.Name == "BaseColor") meshJson["BaseColor"] = Vec3ToJson(mesh.BaseColor);
|
||
else if (meshField.Name == "ModelNodeIndex") meshJson["ModelNodeIndex"] = mesh.ModelNodeIndex;
|
||
else if (meshField.Name == "SubMeshIndex") meshJson["SubMeshIndex"] = mesh.SubMeshIndex;
|
||
else if (meshField.Name == "Visible") meshJson["Visible"] = mesh.Visible;
|
||
}
|
||
objJson["MeshRenderer"] = meshJson;
|
||
}
|
||
} else if (objField.Name == "Light" && obj.Light.has_value()) {
|
||
const MetaCoreStructDescriptor* lightDesc = registry.FindStruct<MetaCoreLightComponent>();
|
||
if (lightDesc) {
|
||
json lightJson = json::object();
|
||
for (const auto& lightField : lightDesc->Fields) {
|
||
if (lightField.Name == "Color") lightJson["Color"] = Vec3ToJson(obj.Light->Color);
|
||
else if (lightField.Name == "Intensity") lightJson["Intensity"] = obj.Light->Intensity;
|
||
else if (lightField.Name == "Enabled") lightJson["Enabled"] = obj.Light->Enabled;
|
||
}
|
||
objJson["Light"] = lightJson;
|
||
}
|
||
} else if (objField.Name == "Rotator" && obj.Rotator.has_value()) {
|
||
const MetaCoreStructDescriptor* rotatorDesc = registry.FindStruct<MetaCoreRotatorComponent>();
|
||
if (rotatorDesc) {
|
||
json rotatorJson = json::object();
|
||
for (const auto& rotatorField : rotatorDesc->Fields) {
|
||
if (rotatorField.Name == "Enabled") rotatorJson["Enabled"] = obj.Rotator->Enabled;
|
||
else if (rotatorField.Name == "DegreesPerSecond") rotatorJson["DegreesPerSecond"] = obj.Rotator->DegreesPerSecond;
|
||
}
|
||
objJson["Rotator"] = rotatorJson;
|
||
}
|
||
} else if (objField.Name == "Animator" && obj.Animator.has_value()) {
|
||
const MetaCoreStructDescriptor* animatorDesc = registry.FindStruct<MetaCoreAnimatorComponent>();
|
||
if (animatorDesc) {
|
||
json animatorJson = json::object();
|
||
const auto& animator = obj.Animator.value();
|
||
for (const auto& animatorField : animatorDesc->Fields) {
|
||
if (animatorField.Name == "Enabled") animatorJson["Enabled"] = animator.Enabled;
|
||
else if (animatorField.Name == "SourceModelAssetGuid") animatorJson["SourceModelAssetGuid"] = GuidToString(animator.SourceModelAssetGuid);
|
||
else if (animatorField.Name == "SourceModelPath") animatorJson["SourceModelPath"] = animator.SourceModelPath;
|
||
else if (animatorField.Name == "ClipIndex") animatorJson["ClipIndex"] = animator.ClipIndex;
|
||
else if (animatorField.Name == "ClipName") animatorJson["ClipName"] = animator.ClipName;
|
||
else if (animatorField.Name == "PlayOnStart") animatorJson["PlayOnStart"] = animator.PlayOnStart;
|
||
else if (animatorField.Name == "Loop") animatorJson["Loop"] = animator.Loop;
|
||
else if (animatorField.Name == "Speed") animatorJson["Speed"] = animator.Speed;
|
||
}
|
||
objJson["Animator"] = std::move(animatorJson);
|
||
}
|
||
} else if (objField.Name == "Script" && obj.Script.has_value()) {
|
||
json scriptJson = json::object();
|
||
json instancesJson = json::array();
|
||
for (const MetaCoreScriptInstanceData& instance : obj.Script->Instances) {
|
||
json instanceJson = json::object();
|
||
instanceJson["InstanceId"] = instance.InstanceId;
|
||
instanceJson["ScriptTypeId"] = instance.ScriptTypeId;
|
||
instanceJson["Enabled"] = instance.Enabled;
|
||
instanceJson["FieldsJson"] = instance.FieldsJson;
|
||
instancesJson.push_back(std::move(instanceJson));
|
||
}
|
||
scriptJson["Instances"] = std::move(instancesJson);
|
||
objJson["Script"] = std::move(scriptJson);
|
||
} else if (objField.Name == "UiRenderer" && obj.UiRenderer.has_value()) {
|
||
const MetaCoreStructDescriptor* uiDesc = registry.FindStruct<MetaCoreUiRendererComponent>();
|
||
if (uiDesc) {
|
||
json uiJson = json::object();
|
||
const auto& ui = obj.UiRenderer.value();
|
||
for (const auto& uiField : uiDesc->Fields) {
|
||
if (uiField.Name == "UiDocumentAssetGuid") uiJson["UiDocumentAssetGuid"] = GuidToString(ui.UiDocumentAssetGuid);
|
||
else if (uiField.Name == "RenderMode") uiJson["RenderMode"] = static_cast<int>(ui.RenderMode);
|
||
else if (uiField.Name == "Visible") uiJson["Visible"] = ui.Visible;
|
||
else if (uiField.Name == "InputEnabled") uiJson["InputEnabled"] = ui.InputEnabled;
|
||
else if (uiField.Name == "FaceCamera") uiJson["FaceCamera"] = ui.FaceCamera;
|
||
else if (uiField.Name == "Layer") uiJson["Layer"] = ui.Layer;
|
||
else if (uiField.Name == "PixelsPerUnit") uiJson["PixelsPerUnit"] = ui.PixelsPerUnit;
|
||
else if (uiField.Name == "WorldSize") uiJson["WorldSize"] = Vec3ToJson(ui.WorldSize);
|
||
}
|
||
objJson["UiRenderer"] = std::move(uiJson);
|
||
}
|
||
} else if (objField.Name == "Camera" && obj.Camera.has_value()) {
|
||
const MetaCoreStructDescriptor* camDesc = registry.FindStruct<MetaCoreCameraComponent>();
|
||
if (camDesc) {
|
||
json camJson = json::object();
|
||
for (const auto& camField : camDesc->Fields) {
|
||
if (camField.Name == "FieldOfViewDegrees") camJson["FieldOfViewDegrees"] = obj.Camera->FieldOfViewDegrees;
|
||
else if (camField.Name == "NearClip") camJson["NearClip"] = obj.Camera->NearClip;
|
||
else if (camField.Name == "FarClip") camJson["FarClip"] = obj.Camera->FarClip;
|
||
else if (camField.Name == "IsPrimary") camJson["IsPrimary"] = obj.Camera->IsPrimary;
|
||
else if (camField.Name == "Enabled") camJson["Enabled"] = obj.Camera->Enabled;
|
||
else if (camField.Name == "ProjectionMode") camJson["ProjectionMode"] = static_cast<int>(obj.Camera->ProjectionMode);
|
||
else if (camField.Name == "OrthographicSize") camJson["OrthographicSize"] = obj.Camera->OrthographicSize;
|
||
else if (camField.Name == "Depth") camJson["Depth"] = obj.Camera->Depth;
|
||
else if (camField.Name == "CullingMask") camJson["CullingMask"] = obj.Camera->CullingMask;
|
||
else if (camField.Name == "ClearFlags") camJson["ClearFlags"] = static_cast<int>(obj.Camera->ClearFlags);
|
||
else if (camField.Name == "BackgroundColor") camJson["BackgroundColor"] = Vec3ToJson(obj.Camera->BackgroundColor);
|
||
else if (camField.Name == "BackgroundAlpha") camJson["BackgroundAlpha"] = obj.Camera->BackgroundAlpha;
|
||
}
|
||
objJson["Camera"] = camJson;
|
||
}
|
||
} else if (objField.Name == "PrefabInstance" && obj.PrefabInstance.has_value()) {
|
||
const MetaCoreStructDescriptor* prefabDesc = registry.FindStruct<MetaCorePrefabInstanceMetadata>();
|
||
if (prefabDesc) {
|
||
json prefabJson = json::object();
|
||
for (const auto& prefabField : prefabDesc->Fields) {
|
||
if (prefabField.Name == "PrefabAssetGuid") prefabJson["PrefabAssetGuid"] = GuidToString(obj.PrefabInstance->PrefabAssetGuid);
|
||
else if (prefabField.Name == "PrefabObjectId") prefabJson["PrefabObjectId"] = obj.PrefabInstance->PrefabObjectId;
|
||
else if (prefabField.Name == "PrefabInstanceRootId") prefabJson["PrefabInstanceRootId"] = obj.PrefabInstance->PrefabInstanceRootId;
|
||
}
|
||
objJson["PrefabInstance"] = prefabJson;
|
||
}
|
||
}
|
||
}
|
||
return objJson;
|
||
}
|
||
|
||
// 辅助方法:从 json 格式中恢复单个 MetaCoreGameObjectData
|
||
static MetaCoreGameObjectData JsonToGameObjectData(const json& objJson, const MetaCoreTypeRegistry& registry) {
|
||
MetaCoreGameObjectData obj;
|
||
const MetaCoreStructDescriptor* objDesc = registry.FindStruct<MetaCoreGameObjectData>();
|
||
if (!objDesc) return obj;
|
||
|
||
for (const auto& objField : objDesc->Fields) {
|
||
if (objField.Name == "Id" && objJson.contains("Id")) {
|
||
obj.Id = objJson["Id"].get<MetaCoreId>();
|
||
} else if (objField.Name == "ParentId" && objJson.contains("ParentId")) {
|
||
obj.ParentId = objJson["ParentId"].get<MetaCoreId>();
|
||
} else if (objField.Name == "Name" && objJson.contains("Name")) {
|
||
obj.Name = objJson["Name"].get<std::string>();
|
||
} else if (objField.Name == "Transform" && objJson.contains("Transform")) {
|
||
const auto& transJson = objJson["Transform"];
|
||
const MetaCoreStructDescriptor* transDesc = registry.FindStruct<MetaCoreTransformComponent>();
|
||
if (transDesc) {
|
||
for (const auto& transField : transDesc->Fields) {
|
||
if (transField.Name == "Position" && transJson.contains("Position")) {
|
||
obj.Transform.Position = JsonToVec3(transJson["Position"]);
|
||
} else if (transField.Name == "RotationEulerDegrees" && transJson.contains("RotationEulerDegrees")) {
|
||
obj.Transform.RotationEulerDegrees = JsonToVec3(transJson["RotationEulerDegrees"]);
|
||
} else if (transField.Name == "Scale" && transJson.contains("Scale")) {
|
||
obj.Transform.Scale = JsonToVec3(transJson["Scale"]);
|
||
}
|
||
}
|
||
}
|
||
} else if (objField.Name == "MeshRenderer" && objJson.contains("MeshRenderer")) {
|
||
const auto& meshJson = objJson["MeshRenderer"];
|
||
const MetaCoreStructDescriptor* meshDesc = registry.FindStruct<MetaCoreMeshRendererComponent>();
|
||
if (meshDesc) {
|
||
MetaCoreMeshRendererComponent mesh;
|
||
for (const auto& meshField : meshDesc->Fields) {
|
||
if (meshField.Name == "MeshSource" && meshJson.contains("MeshSource")) mesh.MeshSource = static_cast<MetaCoreMeshSourceKind>(meshJson["MeshSource"].get<int>());
|
||
else if (meshField.Name == "BuiltinMesh" && meshJson.contains("BuiltinMesh")) mesh.BuiltinMesh = static_cast<MetaCoreBuiltinMeshType>(meshJson["BuiltinMesh"].get<int>());
|
||
else if (meshField.Name == "MeshAssetGuid" && meshJson.contains("MeshAssetGuid")) mesh.MeshAssetGuid = StringToGuid(meshJson["MeshAssetGuid"].get<std::string>());
|
||
else if (meshField.Name == "MaterialAssetGuids" && meshJson.contains("MaterialAssetGuids") && meshJson["MaterialAssetGuids"].is_array()) {
|
||
for (const auto& mGuidJson : meshJson["MaterialAssetGuids"]) {
|
||
mesh.MaterialAssetGuids.push_back(StringToGuid(mGuidJson.get<std::string>()));
|
||
}
|
||
}
|
||
else if (meshField.Name == "SourceModelAssetGuid" && meshJson.contains("SourceModelAssetGuid")) mesh.SourceModelAssetGuid = StringToGuid(meshJson["SourceModelAssetGuid"].get<std::string>());
|
||
else if (meshField.Name == "SourceModelPath" && meshJson.contains("SourceModelPath")) mesh.SourceModelPath = meshJson["SourceModelPath"].get<std::string>();
|
||
else if (meshField.Name == "SourceNodePath" && meshJson.contains("SourceNodePath")) mesh.SourceNodePath = meshJson["SourceNodePath"].get<std::string>();
|
||
else if (meshField.Name == "BaseColorTextureGuid" && meshJson.contains("BaseColorTextureGuid")) mesh.BaseColorTextureGuid = StringToGuid(meshJson["BaseColorTextureGuid"].get<std::string>());
|
||
else if (meshField.Name == "MetallicRoughnessTextureGuid" && meshJson.contains("MetallicRoughnessTextureGuid")) mesh.MetallicRoughnessTextureGuid = StringToGuid(meshJson["MetallicRoughnessTextureGuid"].get<std::string>());
|
||
else if (meshField.Name == "NormalTextureGuid" && meshJson.contains("NormalTextureGuid")) mesh.NormalTextureGuid = StringToGuid(meshJson["NormalTextureGuid"].get<std::string>());
|
||
else if (meshField.Name == "EmissiveTextureGuid" && meshJson.contains("EmissiveTextureGuid")) mesh.EmissiveTextureGuid = StringToGuid(meshJson["EmissiveTextureGuid"].get<std::string>());
|
||
else if (meshField.Name == "AoTextureGuid" && meshJson.contains("AoTextureGuid")) mesh.AoTextureGuid = StringToGuid(meshJson["AoTextureGuid"].get<std::string>());
|
||
else if (meshField.Name == "BaseColorTexturePath" && meshJson.contains("BaseColorTexturePath")) mesh.BaseColorTexturePath = meshJson["BaseColorTexturePath"].get<std::string>();
|
||
else if (meshField.Name == "MetallicRoughnessTexturePath" && meshJson.contains("MetallicRoughnessTexturePath")) mesh.MetallicRoughnessTexturePath = meshJson["MetallicRoughnessTexturePath"].get<std::string>();
|
||
else if (meshField.Name == "NormalTexturePath" && meshJson.contains("NormalTexturePath")) mesh.NormalTexturePath = meshJson["NormalTexturePath"].get<std::string>();
|
||
else if (meshField.Name == "EmissiveTexturePath" && meshJson.contains("EmissiveTexturePath")) mesh.EmissiveTexturePath = meshJson["EmissiveTexturePath"].get<std::string>();
|
||
else if (meshField.Name == "AoTexturePath" && meshJson.contains("AoTexturePath")) mesh.AoTexturePath = meshJson["AoTexturePath"].get<std::string>();
|
||
else if (meshField.Name == "DoubleSided" && meshJson.contains("DoubleSided")) mesh.DoubleSided = meshJson["DoubleSided"].get<bool>();
|
||
else if (meshField.Name == "Metallic" && meshJson.contains("Metallic")) mesh.Metallic = meshJson["Metallic"].get<float>();
|
||
else if (meshField.Name == "Roughness" && meshJson.contains("Roughness")) mesh.Roughness = meshJson["Roughness"].get<float>();
|
||
else if (meshField.Name == "AlphaMode" && meshJson.contains("AlphaMode")) mesh.AlphaMode = static_cast<MetaCoreMeshAlphaMode>(meshJson["AlphaMode"].get<int>());
|
||
else if (meshField.Name == "AlphaCutoff" && meshJson.contains("AlphaCutoff")) mesh.AlphaCutoff = meshJson["AlphaCutoff"].get<float>();
|
||
else if (meshField.Name == "EmissiveColor" && meshJson.contains("EmissiveColor")) mesh.EmissiveColor = JsonToVec3(meshJson["EmissiveColor"]);
|
||
else if (meshField.Name == "BaseColor" && meshJson.contains("BaseColor")) mesh.BaseColor = JsonToVec3(meshJson["BaseColor"]);
|
||
else if (meshField.Name == "ModelNodeIndex" && meshJson.contains("ModelNodeIndex")) mesh.ModelNodeIndex = meshJson["ModelNodeIndex"].get<std::int32_t>();
|
||
else if (meshField.Name == "SubMeshIndex" && meshJson.contains("SubMeshIndex")) mesh.SubMeshIndex = meshJson["SubMeshIndex"].get<std::int32_t>();
|
||
else if (meshField.Name == "Visible" && meshJson.contains("Visible")) mesh.Visible = meshJson["Visible"].get<bool>();
|
||
}
|
||
obj.MeshRenderer = mesh;
|
||
}
|
||
} else if (objField.Name == "Light" && objJson.contains("Light")) {
|
||
const auto& lightJson = objJson["Light"];
|
||
const MetaCoreStructDescriptor* lightDesc = registry.FindStruct<MetaCoreLightComponent>();
|
||
if (lightDesc) {
|
||
MetaCoreLightComponent light;
|
||
for (const auto& lightField : lightDesc->Fields) {
|
||
if (lightField.Name == "Color" && lightJson.contains("Color")) light.Color = JsonToVec3(lightJson["Color"]);
|
||
else if (lightField.Name == "Intensity" && lightJson.contains("Intensity")) light.Intensity = lightJson["Intensity"].get<float>();
|
||
else if (lightField.Name == "Enabled" && lightJson.contains("Enabled")) light.Enabled = lightJson["Enabled"].get<bool>();
|
||
}
|
||
obj.Light = light;
|
||
}
|
||
} else if (objField.Name == "Rotator" && objJson.contains("Rotator")) {
|
||
const auto& rotatorJson = objJson["Rotator"];
|
||
const MetaCoreStructDescriptor* rotatorDesc = registry.FindStruct<MetaCoreRotatorComponent>();
|
||
if (rotatorDesc) {
|
||
MetaCoreRotatorComponent rotator;
|
||
for (const auto& rotatorField : rotatorDesc->Fields) {
|
||
if (rotatorField.Name == "Enabled" && rotatorJson.contains("Enabled")) rotator.Enabled = rotatorJson["Enabled"].get<bool>();
|
||
else if (rotatorField.Name == "DegreesPerSecond" && rotatorJson.contains("DegreesPerSecond")) rotator.DegreesPerSecond = rotatorJson["DegreesPerSecond"].get<float>();
|
||
}
|
||
obj.Rotator = rotator;
|
||
}
|
||
} else if (objField.Name == "Animator" && objJson.contains("Animator")) {
|
||
const auto& animatorJson = objJson["Animator"];
|
||
const MetaCoreStructDescriptor* animatorDesc = registry.FindStruct<MetaCoreAnimatorComponent>();
|
||
if (animatorDesc) {
|
||
MetaCoreAnimatorComponent animator;
|
||
for (const auto& animatorField : animatorDesc->Fields) {
|
||
if (animatorField.Name == "Enabled" && animatorJson.contains("Enabled")) animator.Enabled = animatorJson["Enabled"].get<bool>();
|
||
else if (animatorField.Name == "SourceModelAssetGuid" && animatorJson.contains("SourceModelAssetGuid")) animator.SourceModelAssetGuid = StringToGuid(animatorJson["SourceModelAssetGuid"].get<std::string>());
|
||
else if (animatorField.Name == "SourceModelPath" && animatorJson.contains("SourceModelPath")) animator.SourceModelPath = animatorJson["SourceModelPath"].get<std::string>();
|
||
else if (animatorField.Name == "ClipIndex" && animatorJson.contains("ClipIndex")) animator.ClipIndex = animatorJson["ClipIndex"].get<std::int32_t>();
|
||
else if (animatorField.Name == "ClipName" && animatorJson.contains("ClipName")) animator.ClipName = animatorJson["ClipName"].get<std::string>();
|
||
else if (animatorField.Name == "PlayOnStart" && animatorJson.contains("PlayOnStart")) animator.PlayOnStart = animatorJson["PlayOnStart"].get<bool>();
|
||
else if (animatorField.Name == "Loop" && animatorJson.contains("Loop")) animator.Loop = animatorJson["Loop"].get<bool>();
|
||
else if (animatorField.Name == "Speed" && animatorJson.contains("Speed")) animator.Speed = animatorJson["Speed"].get<float>();
|
||
}
|
||
obj.Animator = animator;
|
||
}
|
||
} else if (objField.Name == "Script" && objJson.contains("Script")) {
|
||
const auto& scriptJson = objJson["Script"];
|
||
MetaCoreScriptComponent script;
|
||
if (scriptJson.contains("Instances") && scriptJson["Instances"].is_array()) {
|
||
for (const auto& instanceJson : scriptJson["Instances"]) {
|
||
MetaCoreScriptInstanceData instance;
|
||
if (instanceJson.contains("InstanceId")) {
|
||
instance.InstanceId = instanceJson["InstanceId"].get<std::uint64_t>();
|
||
}
|
||
if (instanceJson.contains("ScriptTypeId")) {
|
||
instance.ScriptTypeId = instanceJson["ScriptTypeId"].get<std::string>();
|
||
}
|
||
if (instanceJson.contains("Enabled")) {
|
||
instance.Enabled = instanceJson["Enabled"].get<bool>();
|
||
}
|
||
if (instanceJson.contains("FieldsJson")) {
|
||
instance.FieldsJson = instanceJson["FieldsJson"].get<std::string>();
|
||
}
|
||
if (!instance.ScriptTypeId.empty()) {
|
||
script.Instances.push_back(std::move(instance));
|
||
}
|
||
}
|
||
}
|
||
if (!script.Instances.empty()) {
|
||
obj.Script = std::move(script);
|
||
}
|
||
} else if (objField.Name == "UiRenderer" && objJson.contains("UiRenderer")) {
|
||
const auto& uiJson = objJson["UiRenderer"];
|
||
const MetaCoreStructDescriptor* uiDesc = registry.FindStruct<MetaCoreUiRendererComponent>();
|
||
if (uiDesc) {
|
||
MetaCoreUiRendererComponent ui;
|
||
for (const auto& uiField : uiDesc->Fields) {
|
||
if (uiField.Name == "UiDocumentAssetGuid" && uiJson.contains("UiDocumentAssetGuid")) ui.UiDocumentAssetGuid = StringToGuid(uiJson["UiDocumentAssetGuid"].get<std::string>());
|
||
else if (uiField.Name == "RenderMode" && uiJson.contains("RenderMode")) ui.RenderMode = static_cast<MetaCoreUiRenderMode>(uiJson["RenderMode"].get<int>());
|
||
else if (uiField.Name == "Visible" && uiJson.contains("Visible")) ui.Visible = uiJson["Visible"].get<bool>();
|
||
else if (uiField.Name == "InputEnabled" && uiJson.contains("InputEnabled")) ui.InputEnabled = uiJson["InputEnabled"].get<bool>();
|
||
else if (uiField.Name == "FaceCamera" && uiJson.contains("FaceCamera")) ui.FaceCamera = uiJson["FaceCamera"].get<bool>();
|
||
else if (uiField.Name == "Layer" && uiJson.contains("Layer")) ui.Layer = uiJson["Layer"].get<std::int32_t>();
|
||
else if (uiField.Name == "PixelsPerUnit" && uiJson.contains("PixelsPerUnit")) ui.PixelsPerUnit = uiJson["PixelsPerUnit"].get<float>();
|
||
else if (uiField.Name == "WorldSize" && uiJson.contains("WorldSize")) ui.WorldSize = JsonToVec3(uiJson["WorldSize"]);
|
||
}
|
||
obj.UiRenderer = ui;
|
||
}
|
||
} else if (objField.Name == "Camera" && objJson.contains("Camera")) {
|
||
const auto& camJson = objJson["Camera"];
|
||
const MetaCoreStructDescriptor* camDesc = registry.FindStruct<MetaCoreCameraComponent>();
|
||
if (camDesc) {
|
||
MetaCoreCameraComponent cam;
|
||
for (const auto& camField : camDesc->Fields) {
|
||
if (camField.Name == "FieldOfViewDegrees" && camJson.contains("FieldOfViewDegrees")) cam.FieldOfViewDegrees = camJson["FieldOfViewDegrees"].get<float>();
|
||
else if (camField.Name == "NearClip" && camJson.contains("NearClip")) cam.NearClip = camJson["NearClip"].get<float>();
|
||
else if (camField.Name == "FarClip" && camJson.contains("FarClip")) cam.FarClip = camJson["FarClip"].get<float>();
|
||
else if (camField.Name == "IsPrimary" && camJson.contains("IsPrimary")) cam.IsPrimary = camJson["IsPrimary"].get<bool>();
|
||
else if (camField.Name == "Enabled" && camJson.contains("Enabled")) cam.Enabled = camJson["Enabled"].get<bool>();
|
||
else if (camField.Name == "ProjectionMode" && camJson.contains("ProjectionMode")) cam.ProjectionMode = static_cast<MetaCoreCameraProjectionMode>(camJson["ProjectionMode"].get<int>());
|
||
else if (camField.Name == "OrthographicSize" && camJson.contains("OrthographicSize")) cam.OrthographicSize = camJson["OrthographicSize"].get<float>();
|
||
else if (camField.Name == "Depth" && camJson.contains("Depth")) cam.Depth = camJson["Depth"].get<float>();
|
||
else if (camField.Name == "CullingMask" && camJson.contains("CullingMask")) cam.CullingMask = camJson["CullingMask"].get<std::uint32_t>();
|
||
else if (camField.Name == "ClearFlags" && camJson.contains("ClearFlags")) cam.ClearFlags = static_cast<MetaCoreCameraClearFlags>(camJson["ClearFlags"].get<int>());
|
||
else if (camField.Name == "BackgroundColor" && camJson.contains("BackgroundColor")) cam.BackgroundColor = JsonToVec3(camJson["BackgroundColor"]);
|
||
else if (camField.Name == "BackgroundAlpha" && camJson.contains("BackgroundAlpha")) cam.BackgroundAlpha = camJson["BackgroundAlpha"].get<float>();
|
||
}
|
||
obj.Camera = cam;
|
||
}
|
||
} else if (objField.Name == "PrefabInstance" && objJson.contains("PrefabInstance")) {
|
||
const auto& prefabJson = objJson["PrefabInstance"];
|
||
const MetaCoreStructDescriptor* prefabDesc = registry.FindStruct<MetaCorePrefabInstanceMetadata>();
|
||
if (prefabDesc) {
|
||
MetaCorePrefabInstanceMetadata prefab;
|
||
for (const auto& prefabField : prefabDesc->Fields) {
|
||
if (prefabField.Name == "PrefabAssetGuid" && prefabJson.contains("PrefabAssetGuid")) prefab.PrefabAssetGuid = StringToGuid(prefabJson["PrefabAssetGuid"].get<std::string>());
|
||
else if (prefabField.Name == "PrefabObjectId" && prefabJson.contains("PrefabObjectId")) prefab.PrefabObjectId = prefabJson["PrefabObjectId"].get<MetaCoreId>();
|
||
else if (prefabField.Name == "PrefabInstanceRootId" && prefabJson.contains("PrefabInstanceRootId")) prefab.PrefabInstanceRootId = prefabJson["PrefabInstanceRootId"].get<MetaCoreId>();
|
||
}
|
||
obj.PrefabInstance = prefab;
|
||
}
|
||
}
|
||
}
|
||
return obj;
|
||
}
|
||
|
||
bool MetaCoreSceneSerializer::SaveSceneToJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreSceneDocument& sceneDocument,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
try {
|
||
json sceneJson;
|
||
|
||
// 验证 MetaCoreSceneDocument 反射注册
|
||
const MetaCoreStructDescriptor* sceneDesc = registry.FindStruct<MetaCoreSceneDocument>();
|
||
if (!sceneDesc) {
|
||
std::cerr << "SaveSceneToJson: 未能找到 MetaCoreSceneDocument 反射描述" << std::endl;
|
||
return false;
|
||
}
|
||
|
||
for (const auto& field : sceneDesc->Fields) {
|
||
if (field.Name == "Name") {
|
||
sceneJson["SceneName"] = sceneDocument.Name;
|
||
} else if (field.Name == "Environment") {
|
||
sceneJson["Environment"] = SceneEnvironmentToJson(sceneDocument.Environment);
|
||
} else if (field.Name == "Selection") {
|
||
const MetaCoreStructDescriptor* selDesc = registry.FindStruct<MetaCoreEditorSelectionSnapshot>();
|
||
if (selDesc) {
|
||
json selJson = json::object();
|
||
for (const auto& selField : selDesc->Fields) {
|
||
if (selField.Name == "SelectedObjectIds") selJson["SelectedObjectIds"] = sceneDocument.Selection.SelectedObjectIds;
|
||
else if (selField.Name == "ActiveObjectId") selJson["ActiveObjectId"] = sceneDocument.Selection.ActiveObjectId;
|
||
else if (selField.Name == "SelectionAnchorId") selJson["SelectionAnchorId"] = sceneDocument.Selection.SelectionAnchorId;
|
||
}
|
||
sceneJson["Selection"] = selJson;
|
||
}
|
||
} else if (field.Name == "GameObjects") {
|
||
json gameObjectsArray = json::array();
|
||
for (const auto& obj : sceneDocument.GameObjects) {
|
||
gameObjectsArray.push_back(GameObjectDataToJson(obj, registry));
|
||
}
|
||
sceneJson["GameObjects"] = gameObjectsArray;
|
||
}
|
||
}
|
||
|
||
std::ofstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
std::cerr << "SaveSceneToJson: 无法打开文件写入 " << absolutePath << std::endl;
|
||
return false;
|
||
}
|
||
|
||
file << sceneJson.dump(4);
|
||
return true;
|
||
} catch (const std::exception& e) {
|
||
std::cerr << "SaveSceneToJson: 发生异常 - " << e.what() << std::endl;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
std::optional<MetaCoreSceneDocument> MetaCoreSceneSerializer::LoadSceneFromJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
try {
|
||
std::ifstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
std::cerr << "LoadSceneFromJson: 无法打开文件进行读取 " << absolutePath << std::endl;
|
||
return std::nullopt;
|
||
}
|
||
|
||
json sceneJson;
|
||
file >> sceneJson;
|
||
|
||
MetaCoreSceneDocument sceneDocument;
|
||
|
||
// 验证 MetaCoreSceneDocument 反射注册
|
||
const MetaCoreStructDescriptor* sceneDesc = registry.FindStruct<MetaCoreSceneDocument>();
|
||
if (!sceneDesc) {
|
||
std::cerr << "LoadSceneFromJson: 未能找到 MetaCoreSceneDocument 反射描述" << std::endl;
|
||
return std::nullopt;
|
||
}
|
||
|
||
for (const auto& field : sceneDesc->Fields) {
|
||
if (field.Name == "Name" && sceneJson.contains("SceneName")) {
|
||
sceneDocument.Name = sceneJson["SceneName"].get<std::string>();
|
||
} else if (field.Name == "Environment" && sceneJson.contains("Environment")) {
|
||
sceneDocument.Environment = JsonToSceneEnvironment(sceneJson["Environment"]);
|
||
} else if (field.Name == "Selection" && sceneJson.contains("Selection")) {
|
||
const auto& selectionJson = sceneJson["Selection"];
|
||
const MetaCoreStructDescriptor* selDesc = registry.FindStruct<MetaCoreEditorSelectionSnapshot>();
|
||
if (selDesc) {
|
||
for (const auto& selField : selDesc->Fields) {
|
||
if (selField.Name == "SelectedObjectIds" && selectionJson.contains("SelectedObjectIds")) {
|
||
sceneDocument.Selection.SelectedObjectIds = selectionJson["SelectedObjectIds"].get<std::vector<MetaCoreId>>();
|
||
} else if (selField.Name == "ActiveObjectId" && selectionJson.contains("ActiveObjectId")) {
|
||
sceneDocument.Selection.ActiveObjectId = selectionJson["ActiveObjectId"].get<MetaCoreId>();
|
||
} else if (selField.Name == "SelectionAnchorId" && selectionJson.contains("SelectionAnchorId")) {
|
||
sceneDocument.Selection.SelectionAnchorId = selectionJson["SelectionAnchorId"].get<MetaCoreId>();
|
||
}
|
||
}
|
||
}
|
||
} else if (field.Name == "GameObjects" && sceneJson.contains("GameObjects") && sceneJson["GameObjects"].is_array()) {
|
||
for (const auto& objJson : sceneJson["GameObjects"]) {
|
||
sceneDocument.GameObjects.push_back(JsonToGameObjectData(objJson, registry));
|
||
}
|
||
}
|
||
}
|
||
|
||
return sceneDocument;
|
||
} catch (const std::exception& e) {
|
||
std::cerr << "LoadSceneFromJson: 发生异常 - " << e.what() << std::endl;
|
||
return std::nullopt;
|
||
}
|
||
}
|
||
|
||
// Prefab
|
||
bool MetaCoreSceneSerializer::SavePrefabToJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCorePrefabDocument& prefabDocument,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
try {
|
||
json prefabJson;
|
||
prefabJson["PrefabName"] = prefabDocument.Name;
|
||
json gameObjectsArray = json::array();
|
||
for (const auto& obj : prefabDocument.GameObjects) {
|
||
gameObjectsArray.push_back(GameObjectDataToJson(obj, registry));
|
||
}
|
||
prefabJson["GameObjects"] = gameObjectsArray;
|
||
|
||
std::ofstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return false;
|
||
}
|
||
file << prefabJson.dump(4);
|
||
return true;
|
||
} catch (...) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
std::optional<MetaCorePrefabDocument> MetaCoreSceneSerializer::LoadPrefabFromJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
try {
|
||
std::ifstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return std::nullopt;
|
||
}
|
||
json prefabJson;
|
||
file >> prefabJson;
|
||
|
||
MetaCorePrefabDocument doc;
|
||
if (prefabJson.contains("PrefabName")) {
|
||
doc.Name = prefabJson["PrefabName"].get<std::string>();
|
||
}
|
||
if (prefabJson.contains("GameObjects") && prefabJson["GameObjects"].is_array()) {
|
||
for (const auto& objJson : prefabJson["GameObjects"]) {
|
||
doc.GameObjects.push_back(JsonToGameObjectData(objJson, registry));
|
||
}
|
||
}
|
||
return doc;
|
||
} catch (...) {
|
||
return std::nullopt;
|
||
}
|
||
}
|
||
|
||
// Material
|
||
bool MetaCoreSceneSerializer::SaveMaterialToJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreMaterialAssetDocument& doc,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
(void)registry;
|
||
try {
|
||
json matJson;
|
||
matJson["AssetGuid"] = GuidToString(doc.AssetGuid);
|
||
matJson["Name"] = doc.Name;
|
||
matJson["StableImportKey"] = doc.StableImportKey;
|
||
matJson["ShaderModel"] = static_cast<int>(doc.ShaderModel);
|
||
matJson["BaseColor"] = Vec3ToJson(doc.BaseColor);
|
||
matJson["BaseColorTexture"] = GuidToString(doc.BaseColorTexture);
|
||
matJson["NormalTexture"] = GuidToString(doc.NormalTexture);
|
||
matJson["Metallic"] = doc.Metallic;
|
||
matJson["Roughness"] = doc.Roughness;
|
||
matJson["MetallicRoughnessTexture"] = GuidToString(doc.MetallicRoughnessTexture);
|
||
matJson["AoTexture"] = GuidToString(doc.AoTexture);
|
||
matJson["EmissiveColor"] = Vec3ToJson(doc.EmissiveColor);
|
||
matJson["EmissiveTexture"] = GuidToString(doc.EmissiveTexture);
|
||
matJson["AlphaMode"] = static_cast<int>(doc.AlphaMode);
|
||
matJson["AlphaCutoff"] = doc.AlphaCutoff;
|
||
matJson["DoubleSided"] = doc.DoubleSided;
|
||
|
||
std::ofstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return false;
|
||
}
|
||
file << matJson.dump(4);
|
||
return true;
|
||
} catch (...) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
std::optional<MetaCoreMaterialAssetDocument> MetaCoreSceneSerializer::LoadMaterialFromJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
(void)registry;
|
||
try {
|
||
std::ifstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return std::nullopt;
|
||
}
|
||
json matJson;
|
||
file >> matJson;
|
||
|
||
MetaCoreMaterialAssetDocument doc;
|
||
if (matJson.contains("AssetGuid")) doc.AssetGuid = StringToGuid(matJson["AssetGuid"].get<std::string>());
|
||
if (matJson.contains("Name")) doc.Name = matJson["Name"].get<std::string>();
|
||
if (matJson.contains("StableImportKey")) doc.StableImportKey = matJson["StableImportKey"].get<std::string>();
|
||
if (matJson.contains("ShaderModel")) doc.ShaderModel = static_cast<MetaCoreMaterialShaderModel>(matJson["ShaderModel"].get<int>());
|
||
if (matJson.contains("BaseColor")) doc.BaseColor = JsonToVec3(matJson["BaseColor"]);
|
||
if (matJson.contains("BaseColorTexture")) doc.BaseColorTexture = StringToGuid(matJson["BaseColorTexture"].get<std::string>());
|
||
if (matJson.contains("NormalTexture")) doc.NormalTexture = StringToGuid(matJson["NormalTexture"].get<std::string>());
|
||
if (matJson.contains("Metallic")) doc.Metallic = matJson["Metallic"].get<float>();
|
||
if (matJson.contains("Roughness")) doc.Roughness = matJson["Roughness"].get<float>();
|
||
if (matJson.contains("MetallicRoughnessTexture")) doc.MetallicRoughnessTexture = StringToGuid(matJson["MetallicRoughnessTexture"].get<std::string>());
|
||
if (matJson.contains("AoTexture")) doc.AoTexture = StringToGuid(matJson["AoTexture"].get<std::string>());
|
||
if (matJson.contains("EmissiveColor")) doc.EmissiveColor = JsonToVec3(matJson["EmissiveColor"]);
|
||
if (matJson.contains("EmissiveTexture")) doc.EmissiveTexture = StringToGuid(matJson["EmissiveTexture"].get<std::string>());
|
||
if (matJson.contains("AlphaMode")) doc.AlphaMode = static_cast<MetaCoreMaterialAlphaMode>(matJson["AlphaMode"].get<int>());
|
||
if (matJson.contains("AlphaCutoff")) doc.AlphaCutoff = matJson["AlphaCutoff"].get<float>();
|
||
if (matJson.contains("DoubleSided")) doc.DoubleSided = matJson["DoubleSided"].get<bool>();
|
||
|
||
return doc;
|
||
} catch (...) {
|
||
return std::nullopt;
|
||
}
|
||
}
|
||
|
||
// UI 序列化辅助方法
|
||
static json RectTransformToJson(const MetaCoreUiRectTransformDocument& trans) {
|
||
json j = json::object();
|
||
j["AnchorMin"] = Vec3ToJson(trans.AnchorMin);
|
||
j["AnchorMax"] = Vec3ToJson(trans.AnchorMax);
|
||
j["Pivot"] = Vec3ToJson(trans.Pivot);
|
||
j["Position"] = Vec3ToJson(trans.Position);
|
||
j["Size"] = Vec3ToJson(trans.Size);
|
||
return j;
|
||
}
|
||
|
||
static MetaCoreUiRectTransformDocument JsonToRectTransform(const json& j) {
|
||
MetaCoreUiRectTransformDocument trans;
|
||
if (j.contains("AnchorMin")) trans.AnchorMin = JsonToVec3(j["AnchorMin"]);
|
||
if (j.contains("AnchorMax")) trans.AnchorMax = JsonToVec3(j["AnchorMax"]);
|
||
if (j.contains("Pivot")) trans.Pivot = JsonToVec3(j["Pivot"]);
|
||
if (j.contains("Position")) trans.Position = JsonToVec3(j["Position"]);
|
||
if (j.contains("Size")) trans.Size = JsonToVec3(j["Size"]);
|
||
return trans;
|
||
}
|
||
|
||
static json UiStyleToJson(const MetaCoreUiStyleDocument& style) {
|
||
json j = json::object();
|
||
j["BackgroundColor"] = Vec3ToJson(style.BackgroundColor);
|
||
j["TextColor"] = Vec3ToJson(style.TextColor);
|
||
j["TintColor"] = Vec3ToJson(style.TintColor);
|
||
j["FontSize"] = style.FontSize;
|
||
j["Padding"] = Vec3ToJson(style.Padding);
|
||
j["HorizontalAlignment"] = static_cast<int>(style.HorizontalAlignment);
|
||
j["VerticalAlignment"] = static_cast<int>(style.VerticalAlignment);
|
||
j["ImageAssetGuid"] = GuidToString(style.ImageAssetGuid);
|
||
j["PreserveAspect"] = style.PreserveAspect;
|
||
return j;
|
||
}
|
||
|
||
static MetaCoreUiStyleDocument JsonToUiStyle(const json& j) {
|
||
MetaCoreUiStyleDocument style;
|
||
if (j.contains("BackgroundColor")) style.BackgroundColor = JsonToVec3(j["BackgroundColor"]);
|
||
if (j.contains("TextColor")) style.TextColor = JsonToVec3(j["TextColor"]);
|
||
if (j.contains("TintColor")) style.TintColor = JsonToVec3(j["TintColor"]);
|
||
if (j.contains("FontSize")) style.FontSize = j["FontSize"].get<float>();
|
||
if (j.contains("Padding")) style.Padding = JsonToVec3(j["Padding"]);
|
||
if (j.contains("HorizontalAlignment")) style.HorizontalAlignment = static_cast<MetaCoreUiHorizontalAlignment>(j["HorizontalAlignment"].get<int>());
|
||
if (j.contains("VerticalAlignment")) style.VerticalAlignment = static_cast<MetaCoreUiVerticalAlignment>(j["VerticalAlignment"].get<int>());
|
||
if (j.contains("ImageAssetGuid")) style.ImageAssetGuid = StringToGuid(j["ImageAssetGuid"].get<std::string>());
|
||
if (j.contains("PreserveAspect")) style.PreserveAspect = j["PreserveAspect"].get<bool>();
|
||
return style;
|
||
}
|
||
|
||
static json UiNodeToJson(const MetaCoreUiNodeDocument& node) {
|
||
json j = json::object();
|
||
j["Id"] = node.Id;
|
||
j["Name"] = node.Name;
|
||
j["Type"] = static_cast<int>(node.Type);
|
||
j["ParentId"] = node.ParentId;
|
||
j["Children"] = node.Children;
|
||
j["Visible"] = node.Visible;
|
||
j["RectTransform"] = RectTransformToJson(node.RectTransform);
|
||
j["Style"] = UiStyleToJson(node.Style);
|
||
j["Text"] = node.Text;
|
||
j["Interactable"] = node.Interactable;
|
||
j["Action"] = node.Action;
|
||
j["DataBinding"] = node.DataBinding;
|
||
j["DataFormat"] = node.DataFormat;
|
||
return j;
|
||
}
|
||
|
||
static MetaCoreUiNodeDocument JsonToUiNode(const json& j) {
|
||
MetaCoreUiNodeDocument node;
|
||
if (j.contains("Id")) node.Id = j["Id"].get<std::string>();
|
||
if (j.contains("Name")) node.Name = j["Name"].get<std::string>();
|
||
if (j.contains("Type")) node.Type = static_cast<MetaCoreUiNodeType>(j["Type"].get<int>());
|
||
if (j.contains("ParentId")) node.ParentId = j["ParentId"].get<std::string>();
|
||
if (j.contains("Children")) node.Children = j["Children"].get<std::vector<std::string>>();
|
||
if (j.contains("Visible")) node.Visible = j["Visible"].get<bool>();
|
||
if (j.contains("RectTransform")) node.RectTransform = JsonToRectTransform(j["RectTransform"]);
|
||
if (j.contains("Style")) node.Style = JsonToUiStyle(j["Style"]);
|
||
if (j.contains("Text")) node.Text = j["Text"].get<std::string>();
|
||
if (j.contains("Interactable")) node.Interactable = j["Interactable"].get<bool>();
|
||
if (j.contains("Action")) node.Action = j["Action"].get<std::string>();
|
||
if (j.contains("DataBinding")) node.DataBinding = j["DataBinding"].get<std::string>();
|
||
if (j.contains("DataFormat")) node.DataFormat = j["DataFormat"].get<std::string>();
|
||
return node;
|
||
}
|
||
|
||
bool MetaCoreSceneSerializer::SaveUiToJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreUiDocument& uiDocument,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
(void)registry;
|
||
try {
|
||
json uiJson;
|
||
uiJson["Name"] = uiDocument.Name;
|
||
uiJson["ReferenceWidth"] = uiDocument.ReferenceWidth;
|
||
uiJson["ReferenceHeight"] = uiDocument.ReferenceHeight;
|
||
uiJson["BackgroundColor"] = Vec3ToJson(uiDocument.BackgroundColor);
|
||
uiJson["BackgroundAlpha"] = uiDocument.BackgroundAlpha;
|
||
uiJson["RootNodeIds"] = uiDocument.RootNodeIds;
|
||
|
||
json nodesArray = json::array();
|
||
for (const auto& node : uiDocument.Nodes) {
|
||
nodesArray.push_back(UiNodeToJson(node));
|
||
}
|
||
uiJson["Nodes"] = nodesArray;
|
||
|
||
std::ofstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return false;
|
||
}
|
||
file << uiJson.dump(4);
|
||
return true;
|
||
} catch (...) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
std::optional<MetaCoreUiDocument> MetaCoreSceneSerializer::LoadUiFromJson(
|
||
const std::filesystem::path& absolutePath,
|
||
const MetaCoreTypeRegistry& registry
|
||
) {
|
||
(void)registry;
|
||
try {
|
||
std::ifstream file(absolutePath);
|
||
if (!file.is_open()) {
|
||
return std::nullopt;
|
||
}
|
||
json uiJson;
|
||
file >> uiJson;
|
||
|
||
MetaCoreUiDocument doc;
|
||
if (uiJson.contains("Name")) doc.Name = uiJson["Name"].get<std::string>();
|
||
if (uiJson.contains("ReferenceWidth")) doc.ReferenceWidth = uiJson["ReferenceWidth"].get<std::int32_t>();
|
||
if (uiJson.contains("ReferenceHeight")) doc.ReferenceHeight = uiJson["ReferenceHeight"].get<std::int32_t>();
|
||
if (uiJson.contains("BackgroundColor")) doc.BackgroundColor = JsonToVec3(uiJson["BackgroundColor"]);
|
||
if (uiJson.contains("BackgroundAlpha")) doc.BackgroundAlpha = uiJson["BackgroundAlpha"].get<float>();
|
||
if (uiJson.contains("RootNodeIds")) doc.RootNodeIds = uiJson["RootNodeIds"].get<std::vector<std::string>>();
|
||
|
||
if (uiJson.contains("Nodes") && uiJson["Nodes"].is_array()) {
|
||
for (const auto& nodeJson : uiJson["Nodes"]) {
|
||
doc.Nodes.push_back(JsonToUiNode(nodeJson));
|
||
}
|
||
}
|
||
return doc;
|
||
} catch (...) {
|
||
return std::nullopt;
|
||
}
|
||
}
|
||
|
||
} // namespace MetaCore
|