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>
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2021-10-05 13:44:32 +03:30
|
|
|
namespace YAML {
|
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
template<>
|
|
|
|
struct convert<glm::vec3>
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto encode(const glm::vec3 &rhs) -> Node
|
2021-10-05 13:44:32 +03:30
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto node = Node {};
|
2022-03-07 21:57:00 +03:30
|
|
|
node.push_back(rhs.x);
|
|
|
|
node.push_back(rhs.y);
|
|
|
|
node.push_back(rhs.z);
|
|
|
|
return node;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto decode(const Node &node, glm::vec3 &rhs) -> bool
|
2021-10-05 13:44:32 +03:30
|
|
|
{
|
2025-07-06 16:52:50 +03:30
|
|
|
if (!node.IsSequence() || node.size() != 3) {
|
2022-03-07 21:57:00 +03:30
|
|
|
return false;
|
2025-07-06 16:52:50 +03:30
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
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;
|
2021-10-05 13:44:32 +03:30
|
|
|
}
|
2022-03-07 21:57:00 +03:30
|
|
|
};
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
template<>
|
|
|
|
struct convert<glm::vec4>
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto encode(const glm::vec4 &rhs) -> Node
|
2021-10-05 13:44:32 +03:30
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto node = Node {};
|
2022-03-07 21:57:00 +03:30
|
|
|
node.push_back(rhs.x);
|
|
|
|
node.push_back(rhs.y);
|
|
|
|
node.push_back(rhs.z);
|
|
|
|
node.push_back(rhs.w);
|
|
|
|
return node;
|
2021-10-05 13:44:32 +03:30
|
|
|
}
|
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto decode(const Node &node, glm::vec4 &rhs) -> bool
|
2021-10-05 13:44:32 +03:30
|
|
|
{
|
2025-07-06 16:52:50 +03:30
|
|
|
if (!node.IsSequence() || node.size() != 4) {
|
2022-03-07 21:57:00 +03:30
|
|
|
return false;
|
2025-07-06 16:52:50 +03:30
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
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
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
namespace Light {
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto operator<<(YAML::Emitter &out, const glm::vec3 &v) -> YAML::Emitter &
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
out << YAML::Flow;
|
|
|
|
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
|
|
|
|
return out;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
static auto operator<<(YAML::Emitter &out, const glm::vec4 &v) -> YAML::Emitter &
|
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;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 14:23:01 +03:30
|
|
|
SceneSerializer::SceneSerializer(const Ref<Scene> &scene): m_scene(scene)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void SceneSerializer::serialize(const std::string &filePath)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto out = YAML::Emitter {};
|
2022-03-07 21:57:00 +03:30
|
|
|
out << YAML::BeginMap; // Scene
|
|
|
|
out << YAML::Key << "Scene" << YAML::Value << "Untitled";
|
|
|
|
|
|
|
|
out << YAML::Key << "Entities" << YAML::Value << YAML::BeginSeq;
|
2025-07-05 14:23:01 +03:30
|
|
|
for (auto [entityID, storage] : m_scene->m_registry.storage())
|
2025-07-05 11:33:43 +03:30
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto entity = Entity { static_cast<entt::entity>(entityID), m_scene.get() };
|
2025-07-05 15:36:53 +03:30
|
|
|
if (!entity.is_valid())
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
return;
|
2025-07-06 16:30:38 +03:30
|
|
|
}
|
2022-03-07 21:57:00 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
serialize_entity(out, entity);
|
2025-07-05 11:33:43 +03:30
|
|
|
};
|
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('\\')));
|
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto fout = std::ofstream { filePath };
|
2022-03-07 21:57:00 +03:30
|
|
|
if (!fout.is_open())
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
|
|
|
log_trc("Failed to create fout at: {}", filePath);
|
|
|
|
}
|
2025-07-06 14:02:50 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
fout << out.c_str();
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 16:30:38 +03:30
|
|
|
auto SceneSerializer::deserialize(const std::string &file_path) -> bool
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 16:30:38 +03:30
|
|
|
auto stream = std::ifstream { file_path };
|
2025-07-06 14:02:50 +03:30
|
|
|
auto ss = std::stringstream {};
|
2022-03-07 21:57:00 +03:30
|
|
|
ss << stream.rdbuf();
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto data = YAML::Load(ss.str());
|
2022-03-07 21:57:00 +03:30
|
|
|
if (!data["Scene"])
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
return false;
|
2025-07-06 16:30:38 +03:30
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto sceneName = data["Scene"].as<std::string>();
|
2025-07-06 16:30:38 +03:30
|
|
|
log_trc("Deserializing scene: '{}'", sceneName);
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
auto entities = data["Entities"];
|
|
|
|
if (entities)
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto texturePaths = std::unordered_set<std::string> {};
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
for (auto entity : entities)
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto uuid = entity["entity"].as<uint64_t>(); // #todo
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto name = std::string {};
|
2022-03-07 21:57:00 +03:30
|
|
|
auto tagComponent = entity["TagComponent"];
|
|
|
|
if (tagComponent)
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
name = tagComponent["Tag"].as<std::string>();
|
2025-07-06 16:30:38 +03:30
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 16:30:38 +03:30
|
|
|
log_trc("Deserialized entity '{}' : '{}'", uuid, name);
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto deserializedEntity = m_scene->create_entity_with_uuid(name, uuid);
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto gg = deserializedEntity.get_component<TagComponent>();
|
2025-07-06 16:30:38 +03:30
|
|
|
log_trc("tag: {}", gg.tag);
|
2022-03-07 21:57:00 +03:30
|
|
|
auto transformComponent = entity["TransformComponent"];
|
|
|
|
if (transformComponent)
|
|
|
|
{
|
2025-07-05 13:28:41 +03:30
|
|
|
auto &entityTransforomComponent = deserializedEntity
|
2025-07-06 14:02:50 +03:30
|
|
|
.get_component<TransformComponent>();
|
2021-10-05 13:44:32 +03:30
|
|
|
|
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
|
|
|
}
|
2021-10-07 01:13:18 +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
|
2025-07-06 14:02:50 +03:30
|
|
|
.add_component<SpriteRendererComponent>();
|
2025-07-05 13:28:41 +03:30
|
|
|
entitySpriteRendererComponent.tint = spriteRendererComponent["Tint"].as<glm::vec4>(
|
|
|
|
);
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto texturePath = spriteRendererComponent["Texture"].as<std::string>();
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
if (!texturePaths.contains(texturePath))
|
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
ResourceManager::load_texture(texturePath, texturePath);
|
2022-03-07 21:57:00 +03:30
|
|
|
texturePaths.insert(texturePath);
|
2021-10-07 01:13:18 +03:30
|
|
|
}
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
entitySpriteRendererComponent.texture = ResourceManager::get_texture(texturePath);
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
/* #TEMPORARY SOLUTION# */
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
auto cameraComponent = entity["CameraComponent"];
|
|
|
|
if (cameraComponent)
|
|
|
|
{
|
2025-07-06 14:02:50 +03:30
|
|
|
auto &entityCameraComponent = deserializedEntity.add_component<CameraComponent>();
|
2025-07-05 13:28:41 +03:30
|
|
|
|
|
|
|
const auto &cameraSpecifications = cameraComponent["Camera"];
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_projection_type(
|
2025-07-05 13:28:41 +03:30
|
|
|
(SceneCamera::ProjectionType)cameraSpecifications["ProjectionType"].as<int>()
|
|
|
|
);
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_orthographic_size(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["OrthographicSize"].as<float>()
|
|
|
|
);
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_orthographic_near_plane(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["OrthographicNearPlane"].as<float>()
|
|
|
|
);
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_orthographic_far_plane(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["OrthographicFarPlane"].as<float>()
|
|
|
|
);
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_perspective_vertical_fov(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["PerspectiveVerticalFOV"].as<float>()
|
|
|
|
);
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_perspective_near_plane(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["PerspectiveNearPlane"].as<float>()
|
|
|
|
);
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_perspective_far_plane(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["PerspectiveFarPlane"].as<float>()
|
|
|
|
);
|
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
entityCameraComponent.camera.set_background_color(
|
2025-07-05 13:28:41 +03:30
|
|
|
cameraSpecifications["BackgroundColor"].as<glm::vec4>()
|
|
|
|
);
|
2021-10-07 01:13:18 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
entityCameraComponent.isPrimary = cameraComponent["IsPrimary"].as<bool>();
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
}
|
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
return true;
|
2021-10-05 13:44:32 +03:30
|
|
|
}
|
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
return false;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 16:52:50 +03:30
|
|
|
void SceneSerializer::serialize_binary(const std::string & /*filePath*/)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 16:30:38 +03:30
|
|
|
log_err("NO_IMPLEMENT");
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 16:52:50 +03:30
|
|
|
auto SceneSerializer::deserialize_binary(const std::string & /*filePath*/) -> bool
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 16:30:38 +03:30
|
|
|
log_err("NO_IMPLEMENT");
|
2022-03-07 21:57:00 +03:30
|
|
|
return false;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void SceneSerializer::serialize_entity(YAML::Emitter &out, Entity entity)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
out << YAML::BeginMap; // entity
|
|
|
|
out << YAML::Key << "entity" << YAML::Value << entity.get_uuid(); // dummy uuid
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
if (entity.has_component<TagComponent>())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
out << YAML::Key << "TagComponent";
|
|
|
|
out << YAML::BeginMap; // tag component
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto &tagComponent = entity.get_component<TagComponent>().tag;
|
2022-03-07 21:57:00 +03:30
|
|
|
out << YAML::Key << "Tag" << YAML::Value << tagComponent;
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
out << YAML::EndMap; // tag component
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
if (entity.has_component<TransformComponent>())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
out << YAML::Key << "TransformComponent";
|
|
|
|
out << YAML::BeginMap; // transform component
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto &transformComponent = entity.get_component<TransformComponent>();
|
2021-10-05 13:44:32 +03:30
|
|
|
|
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;
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
out << YAML::EndMap; // transform component;
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
if (entity.has_component<SpriteRendererComponent>())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
out << YAML::Key << "SpriteRendererComponent";
|
|
|
|
out << YAML::BeginMap; // sprite renderer component;
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto &spriteRendererComponent = entity.get_component<SpriteRendererComponent>();
|
2021-10-05 13:44:32 +03:30
|
|
|
|
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
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
// #todo:
|
2025-07-05 15:36:53 +03:30
|
|
|
// if(entity.has_component<NativeScriptComponent>())
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
if (entity.has_component<CameraComponent>())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
out << YAML::Key << "CameraComponent";
|
|
|
|
out << YAML::BeginMap; // camera component
|
|
|
|
|
2025-07-06 14:02:50 +03:30
|
|
|
auto &cameraComponent = entity.get_component<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
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_orthographic_size();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "OrthographicFarPlane" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_orthographic_far_plane();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "OrthographicNearPlane" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_orthographic_near_plane();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "PerspectiveVerticalFOV" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_perspective_vertical_fov();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "PerspectiveFarPlane" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_perspective_far_plane();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "PerspectiveNearPlane" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< cameraComponent.camera.get_perspective_near_plane();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "ProjectionType" << YAML::Value
|
2025-07-05 15:36:53 +03:30
|
|
|
<< (int)cameraComponent.camera.get_projection_type();
|
2025-07-05 13:28:41 +03:30
|
|
|
out << YAML::Key << "BackgroundColor" << YAML::Value
|
2025-07-06 14:02:50 +03:30
|
|
|
<< cameraComponent.camera.get_background_color();
|
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
|
2021-10-05 13:44:32 +03:30
|
|
|
}
|
2022-03-07 21:57:00 +03:30
|
|
|
out << YAML::EndMap; // entity
|
|
|
|
}
|
2021-10-05 13:44:32 +03:30
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
} // namespace Light
|