light/modules/engine/src/utils/serializer.cpp

311 lines
9 KiB
C++
Raw Normal View History

2025-07-05 13:28:41 +03:30
#include <engine/graphics/texture.hpp>
#include <engine/scene/components.hpp>
#include <engine/utils/resource_manager.hpp>
#include <engine/utils/serializer.hpp>
namespace YAML {
2022-03-07 21:57:00 +03:30
template<>
struct convert<glm::vec3>
{
2025-07-05 13:28:41 +03:30
static Node encode(const glm::vec3 &rhs)
{
2022-03-07 21:57:00 +03:30
Node node;
node.push_back(rhs.x);
node.push_back(rhs.y);
node.push_back(rhs.z);
return node;
}
2025-07-05 13:28:41 +03:30
static bool decode(const Node &node, glm::vec3 &rhs)
{
2022-03-07 21:57:00 +03:30
if (!node.IsSequence() || node.size() != 3)
return false;
2022-03-07 21:57:00 +03:30
rhs.x = node[0].as<float>();
rhs.y = node[1].as<float>();
rhs.z = node[2].as<float>();
return true;
}
2022-03-07 21:57:00 +03:30
};
2022-03-07 21:57:00 +03:30
template<>
struct convert<glm::vec4>
{
2025-07-05 13:28:41 +03:30
static Node encode(const glm::vec4 &rhs)
{
2022-03-07 21:57:00 +03:30
Node node;
node.push_back(rhs.x);
node.push_back(rhs.y);
node.push_back(rhs.z);
node.push_back(rhs.w);
return node;
}
2025-07-05 13:28:41 +03:30
static bool decode(const Node &node, glm::vec4 &rhs)
{
2022-03-07 21:57:00 +03:30
if (!node.IsSequence() || node.size() != 4)
return false;
2022-03-07 21:57:00 +03:30
rhs.x = node[0].as<float>();
rhs.y = node[1].as<float>();
rhs.z = node[2].as<float>();
rhs.w = node[3].as<float>();
return true;
}
};
} // namespace YAML
2022-03-07 21:57:00 +03:30
namespace Light {
2025-07-05 13:28:41 +03:30
static YAML::Emitter &operator<<(YAML::Emitter &out, const glm::vec3 &v)
2022-03-07 21:57:00 +03:30
{
out << YAML::Flow;
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
return out;
}
2025-07-05 13:28:41 +03:30
static YAML::Emitter &operator<<(YAML::Emitter &out, const glm::vec4 &v)
2022-03-07 21:57:00 +03:30
{
out << YAML::Flow;
out << YAML::BeginSeq << v.x << v.y << v.z << v.w << YAML::EndSeq;
return out;
}
2025-07-05 13:28:41 +03:30
SceneSerializer::SceneSerializer(const Ref<Scene> &scene): m_Scene(scene)
2022-03-07 21:57:00 +03:30
{
}
2025-07-05 13:28:41 +03:30
void SceneSerializer::Serialize(const std::string &filePath)
2022-03-07 21:57:00 +03:30
{
YAML::Emitter out;
out << YAML::BeginMap; // Scene
out << YAML::Key << "Scene" << YAML::Value << "Untitled";
out << YAML::Key << "Entities" << YAML::Value << YAML::BeginSeq;
for (auto [entityID, storage] : m_Scene->m_Registry.storage())
{
Entity entity = { static_cast<entt::entity>(entityID), m_Scene.get() };
2022-03-07 21:57:00 +03:30
if (!entity.IsValid())
return;
SerializeEntity(out, entity);
};
2022-03-07 21:57:00 +03:30
out << YAML::EndSeq;
out << YAML::EndMap;
std::filesystem::create_directories(filePath.substr(0ull, filePath.find_last_of('\\')));
std::ofstream fout(filePath);
if (!fout.is_open())
LOG(trace, "Failed to create fout at: {}", filePath);
fout << out.c_str();
}
2025-07-05 13:28:41 +03:30
bool SceneSerializer::Deserialize(const std::string &filePath)
2022-03-07 21:57:00 +03:30
{
std::ifstream stream(filePath);
std::stringstream ss;
ss << stream.rdbuf();
2022-03-07 21:57:00 +03:30
YAML::Node data = YAML::Load(ss.str());
if (!data["Scene"])
return false;
2022-03-07 21:57:00 +03:30
std::string sceneName = data["Scene"].as<std::string>();
LOG(trace, "Deserializing scene: '{}'", sceneName);
2022-03-07 21:57:00 +03:30
auto entities = data["Entities"];
if (entities)
{
/* #TEMPORARY SOLUTION# */
std::unordered_set<std::string> texturePaths;
/* #TEMPORARY SOLUTION# */
2022-03-07 21:57:00 +03:30
for (auto entity : entities)
{
uint64_t uuid = entity["Entity"].as<uint64_t>(); // #todo
2022-03-07 21:57:00 +03:30
std::string name;
auto tagComponent = entity["TagComponent"];
if (tagComponent)
name = tagComponent["Tag"].as<std::string>();
2022-03-07 21:57:00 +03:30
LOG(trace, "Deserialized entity '{}' : '{}'", uuid, name);
2022-03-07 21:57:00 +03:30
Entity deserializedEntity = m_Scene->CreateEntityWithUUID(name, uuid);
2022-03-07 21:57:00 +03:30
TagComponent gg = deserializedEntity.GetComponent<TagComponent>();
LOG(trace, gg.tag);
auto transformComponent = entity["TransformComponent"];
if (transformComponent)
{
2025-07-05 13:28:41 +03:30
auto &entityTransforomComponent = deserializedEntity
.GetComponent<TransformComponent>();
2025-07-05 13:28:41 +03:30
entityTransforomComponent.translation = transformComponent["Translation"]
.as<glm::vec3>();
entityTransforomComponent.rotation = transformComponent["Rotation"].as<glm::vec3>();
entityTransforomComponent.scale = transformComponent["Scale"].as<glm::vec3>();
2022-03-07 21:57:00 +03:30
}
2022-03-07 21:57:00 +03:30
/* #TEMPORARY SOLUTION# */
auto spriteRendererComponent = entity["SpriteRendererComponent"];
if (spriteRendererComponent)
{
2025-07-05 13:28:41 +03:30
auto &entitySpriteRendererComponent = deserializedEntity
.AddComponent<SpriteRendererComponent>();
entitySpriteRendererComponent.tint = spriteRendererComponent["Tint"].as<glm::vec4>(
);
2022-03-07 21:57:00 +03:30
std::string texturePath = spriteRendererComponent["Texture"].as<std::string>();
2022-03-07 21:57:00 +03:30
if (!texturePaths.contains(texturePath))
{
ResourceManager::LoadTexture(texturePath, texturePath);
texturePaths.insert(texturePath);
}
2022-03-07 21:57:00 +03:30
entitySpriteRendererComponent.texture = ResourceManager::GetTexture(texturePath);
}
/* #TEMPORARY SOLUTION# */
2022-03-07 21:57:00 +03:30
auto cameraComponent = entity["CameraComponent"];
if (cameraComponent)
{
2025-07-05 13:28:41 +03:30
auto &entityCameraComponent = deserializedEntity.AddComponent<CameraComponent>();
const auto &cameraSpecifications = cameraComponent["Camera"];
entityCameraComponent.camera.SetProjectionType(
(SceneCamera::ProjectionType)cameraSpecifications["ProjectionType"].as<int>()
);
entityCameraComponent.camera.SetOrthographicSize(
cameraSpecifications["OrthographicSize"].as<float>()
);
entityCameraComponent.camera.SetOrthographicNearPlane(
cameraSpecifications["OrthographicNearPlane"].as<float>()
);
entityCameraComponent.camera.SetOrthographicFarPlane(
cameraSpecifications["OrthographicFarPlane"].as<float>()
);
entityCameraComponent.camera.SetPerspectiveVerticalFOV(
cameraSpecifications["PerspectiveVerticalFOV"].as<float>()
);
entityCameraComponent.camera.SetPerspectiveNearPlane(
cameraSpecifications["PerspectiveNearPlane"].as<float>()
);
entityCameraComponent.camera.SetPerspectiveFarPlane(
cameraSpecifications["PerspectiveFarPlane"].as<float>()
);
entityCameraComponent.camera.SetBackgroundColor(
cameraSpecifications["BackgroundColor"].as<glm::vec4>()
);
2022-03-07 21:57:00 +03:30
entityCameraComponent.isPrimary = cameraComponent["IsPrimary"].as<bool>();
}
}
2022-03-07 21:57:00 +03:30
return true;
}
2022-03-07 21:57:00 +03:30
return false;
}
2025-07-05 13:28:41 +03:30
void SceneSerializer::SerializeBinary(const std::string &filePath)
2022-03-07 21:57:00 +03:30
{
LOG(err, "NO_IMPLEMENT");
}
2025-07-05 13:28:41 +03:30
bool SceneSerializer::DeserializeBinary(const std::string &filePath)
2022-03-07 21:57:00 +03:30
{
LOG(err, "NO_IMPLEMENT");
return false;
}
2025-07-05 13:28:41 +03:30
void SceneSerializer::SerializeEntity(YAML::Emitter &out, Entity entity)
2022-03-07 21:57:00 +03:30
{
out << YAML::BeginMap; // entity
out << YAML::Key << "Entity" << YAML::Value << entity.GetUUID(); // dummy uuid
2022-03-07 21:57:00 +03:30
if (entity.HasComponent<TagComponent>())
{
out << YAML::Key << "TagComponent";
out << YAML::BeginMap; // tag component
2025-07-05 13:28:41 +03:30
auto &tagComponent = entity.GetComponent<TagComponent>().tag;
2022-03-07 21:57:00 +03:30
out << YAML::Key << "Tag" << YAML::Value << tagComponent;
2022-03-07 21:57:00 +03:30
out << YAML::EndMap; // tag component
}
2022-03-07 21:57:00 +03:30
if (entity.HasComponent<TransformComponent>())
{
out << YAML::Key << "TransformComponent";
out << YAML::BeginMap; // transform component
2025-07-05 13:28:41 +03:30
auto &transformComponent = entity.GetComponent<TransformComponent>();
2022-03-07 21:57:00 +03:30
out << YAML::Key << "Translation" << YAML::Value << transformComponent.translation;
out << YAML::Key << "Rotation" << YAML::Value << transformComponent.rotation;
out << YAML::Key << "Scale" << YAML::Value << transformComponent.scale;
2022-03-07 21:57:00 +03:30
out << YAML::EndMap; // transform component;
}
2022-03-07 21:57:00 +03:30
if (entity.HasComponent<SpriteRendererComponent>())
{
out << YAML::Key << "SpriteRendererComponent";
out << YAML::BeginMap; // sprite renderer component;
2025-07-05 13:28:41 +03:30
auto &spriteRendererComponent = entity.GetComponent<SpriteRendererComponent>();
2025-07-05 13:28:41 +03:30
out << YAML::Key << "Texture" << YAML::Value
<< spriteRendererComponent.texture->GetFilePath();
2022-03-07 21:57:00 +03:30
out << YAML::Key << "Tint" << YAML::Value << spriteRendererComponent.tint;
out << YAML::EndMap; // sprite renderer component
}
2022-03-07 21:57:00 +03:30
// #todo:
// if(entity.HasComponent<NativeScriptComponent>())
2022-03-07 21:57:00 +03:30
if (entity.HasComponent<CameraComponent>())
{
out << YAML::Key << "CameraComponent";
out << YAML::BeginMap; // camera component
2025-07-05 13:28:41 +03:30
auto &cameraComponent = entity.GetComponent<CameraComponent>();
2022-03-07 21:57:00 +03:30
out << YAML::Key << "Camera" << YAML::Value;
out << YAML::BeginMap; // camera
2025-07-05 13:28:41 +03:30
out << YAML::Key << "OrthographicSize" << YAML::Value
<< cameraComponent.camera.GetOrthographicSize();
out << YAML::Key << "OrthographicFarPlane" << YAML::Value
<< cameraComponent.camera.GetOrthographicFarPlane();
out << YAML::Key << "OrthographicNearPlane" << YAML::Value
<< cameraComponent.camera.GetOrthographicNearPlane();
out << YAML::Key << "PerspectiveVerticalFOV" << YAML::Value
<< cameraComponent.camera.GetPerspectiveVerticalFOV();
out << YAML::Key << "PerspectiveFarPlane" << YAML::Value
<< cameraComponent.camera.GetPerspectiveFarPlane();
out << YAML::Key << "PerspectiveNearPlane" << YAML::Value
<< cameraComponent.camera.GetPerspectiveNearPlane();
out << YAML::Key << "ProjectionType" << YAML::Value
<< (int)cameraComponent.camera.GetProjectionType();
out << YAML::Key << "BackgroundColor" << YAML::Value
<< cameraComponent.camera.GetBackgroundColor();
2022-03-07 21:57:00 +03:30
out << YAML::EndMap; // camera
out << YAML::Key << "IsPrimary" << YAML::Value << cameraComponent.isPrimary;
out << YAML::EndMap; // camera component
}
2022-03-07 21:57:00 +03:30
out << YAML::EndMap; // entity
}
2022-03-07 21:57:00 +03:30
} // namespace Light