Merge pull request #133 from SHADE-DP/SP3-8-serialization
Resolve serialization errors All components are serialized/deserialized
This commit is contained in:
commit
ca0ecc1641
|
@ -48,15 +48,28 @@ namespace SHADE
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
|
if(skipFrame)
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
skipFrame = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
if(const auto root = sceneGraph.GetRoot())
|
|
||||||
|
if (const auto root = sceneGraph.GetRoot())
|
||||||
{
|
{
|
||||||
auto const& children = root->GetChildren();
|
auto const& children = root->GetChildren();
|
||||||
|
|
||||||
for (const auto child : children)
|
for (const auto child : children)
|
||||||
{
|
{
|
||||||
RecursivelyDrawEntityNode(child);
|
if(child)
|
||||||
|
RecursivelyDrawEntityNode(child);
|
||||||
|
if(skipFrame)
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -119,8 +132,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||||
{
|
{
|
||||||
|
if(currentNode == nullptr)
|
||||||
|
return {};
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
//Get node data (Children, eid, selected)
|
//Get node data (Children, eid, selected)
|
||||||
|
@ -192,10 +207,16 @@ namespace SHADE
|
||||||
if(ImGui::Selectable("Paste"))
|
if(ImGui::Selectable("Paste"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
||||||
|
skipFrame = true;
|
||||||
|
ImGui::EndPopup();
|
||||||
|
if(isNodeOpen)
|
||||||
|
ImGui::TreePop();
|
||||||
|
return nodeRect;
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Paste as Child"))
|
if(ImGui::Selectable("Paste as Child"))
|
||||||
{
|
{
|
||||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
||||||
|
skipFrame = true;
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,10 +26,12 @@ namespace SHADE
|
||||||
void SetScrollTo(EntityID eid);
|
void SetScrollTo(EntityID eid);
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() const noexcept;
|
||||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||||
|
|
||||||
|
bool skipFrame = false;
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
EntityID scrollTo = MAX_EID;
|
EntityID scrollTo = MAX_EID;
|
||||||
|
|
|
@ -146,4 +146,12 @@ namespace SHADE
|
||||||
system->RemoveCollisionShape(GetEID(), index);
|
system->RemoveCollisionShape(GetEID(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace rttr;
|
||||||
|
using namespace SHADE;
|
||||||
|
|
||||||
|
registration::class_<SHColliderComponent>("Collider Component");
|
||||||
|
}
|
|
@ -100,5 +100,6 @@ namespace SHADE
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
Colliders colliders;
|
Colliders colliders;
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
@ -58,7 +59,7 @@ namespace SHADE
|
||||||
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
||||||
{
|
{
|
||||||
EntityID eid = MAX_EID;
|
EntityID eid = MAX_EID;
|
||||||
if(!node)
|
if (!node)
|
||||||
return eid;
|
return eid;
|
||||||
if (node[EIDNode])
|
if (node[EIDNode])
|
||||||
eid = node[EIDNode].as<EntityID>();
|
eid = node[EIDNode].as<EntityID>();
|
||||||
|
@ -71,13 +72,13 @@ namespace SHADE
|
||||||
createdEntities.push_back(eid);
|
createdEntities.push_back(eid);
|
||||||
if (node[NumberOfChildrenNode])
|
if (node[NumberOfChildrenNode])
|
||||||
{
|
{
|
||||||
if(const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
if (const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
||||||
{
|
{
|
||||||
++it;
|
++it;
|
||||||
for (int i = 0; i < numOfChildren; ++i)
|
for (int i = 0; i < numOfChildren; ++i)
|
||||||
{
|
{
|
||||||
DeserializeEntity(it, (*it), createdEntities, eid);
|
DeserializeEntity(it, (*it), createdEntities, eid);
|
||||||
if((i + 1) < numOfChildren)
|
if ((i + 1) < numOfChildren)
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +86,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Deserialise scripts
|
// Deserialise scripts
|
||||||
if (node[ScriptsNode])
|
if (node[ScriptsNode])
|
||||||
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, node[ScriptsNode]);
|
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, node[ScriptsNode]);
|
||||||
|
|
||||||
|
return eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
||||||
|
@ -120,10 +123,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DeserializeEntity(it, (*it), createdEntities);
|
DeserializeEntity(it, (*it), createdEntities);
|
||||||
}
|
}
|
||||||
if(createdEntities.empty())
|
if (createdEntities.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Initialize Entity
|
//Initialize Entity
|
||||||
auto entityVecIt = createdEntities.begin();
|
auto entityVecIt = createdEntities.begin();
|
||||||
|
@ -137,7 +140,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
out << SerializeEntityToNode(entityNode);
|
out << SerializeEntityToNode(entityNode);
|
||||||
auto const& children = entityNode->GetChildren();
|
auto const& children = entityNode->GetChildren();
|
||||||
for(auto const& child : children)
|
for (auto const& child : children)
|
||||||
{
|
{
|
||||||
EmitEntity(child, out);
|
EmitEntity(child, out);
|
||||||
}
|
}
|
||||||
|
@ -162,17 +165,36 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
if (const ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
|
{
|
||||||
|
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void AddConvComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
|
{
|
||||||
|
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = YAML::convert<ComponentType>::encode(*component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
||||||
{
|
{
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
auto eid = sceneNode->GetEntityID();
|
auto eid = sceneNode->GetEntityID();
|
||||||
auto entity = SHEntityManager::GetEntityByID(eid);
|
auto entity = SHEntityManager::GetEntityByID(eid);
|
||||||
if (!sceneNode || !entity)
|
if (!sceneNode && !entity)
|
||||||
{
|
{
|
||||||
node = YAML::Null;
|
node = YAML::Null;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
node.SetStyle(YAML::EmitterStyle::Block);
|
node.SetStyle(YAML::EmitterStyle::Block);
|
||||||
node[EIDNode] = eid;
|
node[EIDNode] = eid;
|
||||||
node[EntityNameNode] = entity->name;
|
node[EntityNameNode] = entity->name;
|
||||||
node[IsActiveNode] = sceneNode->IsActive();
|
node[IsActiveNode] = sceneNode->IsActive();
|
||||||
|
@ -181,22 +203,13 @@ namespace SHADE
|
||||||
|
|
||||||
YAML::Node components;
|
YAML::Node components;
|
||||||
|
|
||||||
if (const auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
AddComponentToComponentNode<SHTransformComponent>(components, eid);
|
||||||
{
|
AddComponentToComponentNode<SHCameraComponent>(components, eid);
|
||||||
components[rttr::type::get<SHTransformComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform);
|
AddConvComponentToComponentNode<SHRenderable>(components, eid);
|
||||||
}
|
AddComponentToComponentNode<SHLightComponent>(components, eid);
|
||||||
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
|
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
|
||||||
{
|
AddConvComponentToComponentNode<SHColliderComponent>(components, eid);
|
||||||
components[rttr::type::get<SHRenderable>().get_name().data()] = *renderable;
|
|
||||||
}
|
|
||||||
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
|
||||||
{
|
|
||||||
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
|
|
||||||
}
|
|
||||||
if(const auto light = SHComponentManager::GetComponent_s<SHLightComponent>(eid))
|
|
||||||
{
|
|
||||||
components[rttr::type::get<SHLightComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(light);
|
|
||||||
}
|
|
||||||
node[ComponentsNode] = components;
|
node[ComponentsNode] = components;
|
||||||
|
|
||||||
YAML::Node scripts;
|
YAML::Node scripts;
|
||||||
|
@ -208,22 +221,22 @@ namespace SHADE
|
||||||
|
|
||||||
EntityID SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept
|
EntityID SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept
|
||||||
{
|
{
|
||||||
if(data.empty())
|
if (data.empty())
|
||||||
return MAX_EID;
|
return MAX_EID;
|
||||||
YAML::Node entities = YAML::Load(data.c_str());
|
YAML::Node entities = YAML::Load(data.c_str());
|
||||||
EntityID eid{MAX_EID};
|
EntityID eid{ MAX_EID };
|
||||||
std::vector<EntityID> createdEntities;
|
std::vector<EntityID> createdEntities;
|
||||||
for(auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
|
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
|
||||||
}
|
}
|
||||||
if(createdEntities.empty())
|
if (createdEntities.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||||
return MAX_EID;
|
return MAX_EID;
|
||||||
}
|
}
|
||||||
auto entityVecIt = createdEntities.begin();
|
auto entityVecIt = createdEntities.begin();
|
||||||
for(auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
InitializeEntity(*it, *entityVecIt++);
|
InitializeEntity(*it, *entityVecIt++);
|
||||||
}
|
}
|
||||||
|
@ -231,33 +244,22 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
static void AddComponentID(std::vector<ComponentTypeID>& idList, YAML::Node const& componentNode)
|
||||||
{
|
{
|
||||||
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
|
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
|
||||||
return { SHFamilyID<SHComponent>::GetID<ComponentType>() };
|
idList.push_back(SHFamilyID<SHComponent>::GetID<ComponentType>());
|
||||||
else
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
|
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
|
||||||
{
|
{
|
||||||
std::vector<ComponentTypeID> componentIDList;
|
std::vector<ComponentTypeID> componentIDList;
|
||||||
|
|
||||||
auto id = GetComponentID<SHTransformComponent>(componentsNode);
|
AddComponentID<SHTransformComponent>(componentIDList, componentsNode);
|
||||||
if (id.has_value())
|
AddComponentID<SHCameraComponent>(componentIDList, componentsNode);
|
||||||
componentIDList.push_back(id.value());
|
AddComponentID<SHRenderable>(componentIDList, componentsNode);
|
||||||
|
AddComponentID<SHRigidBodyComponent>(componentIDList, componentsNode);
|
||||||
id = GetComponentID<SHRenderable>(componentsNode);
|
AddComponentID<SHLightComponent>(componentIDList, componentsNode);
|
||||||
if (id.has_value())
|
AddComponentID<SHColliderComponent>(componentIDList, componentsNode);
|
||||||
componentIDList.push_back(id.value());
|
|
||||||
|
|
||||||
id = GetComponentID<SHRigidBodyComponent>(componentsNode);
|
|
||||||
if (id.has_value())
|
|
||||||
componentIDList.push_back(id.value());
|
|
||||||
|
|
||||||
id = GetComponentID<SHLightComponent>(componentsNode);
|
|
||||||
if(id.has_value())
|
|
||||||
componentIDList.push_back(id.value());
|
|
||||||
|
|
||||||
return componentIDList;
|
return componentIDList;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +270,10 @@ namespace SHADE
|
||||||
if (!componentsNode)
|
if (!componentsNode)
|
||||||
return;
|
return;
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHCameraComponent>(componentsNode, eid);
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
|
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
|
||||||
|
SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,235 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
#include "SHSerializationTools.h"
|
#include "SHSerializationTools.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec4>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
static constexpr const char* z = "z";
|
||||||
|
static constexpr const char* w = "w";
|
||||||
|
|
||||||
|
static Node encode(SHVec4 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
node[z] = rhs.z;
|
||||||
|
node[w] = rhs.w;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec4& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
if (node[z].IsDefined())
|
||||||
|
rhs.z = node[z].as<float>();
|
||||||
|
if (node[w].IsDefined())
|
||||||
|
rhs.w = node[w].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec3>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
static constexpr const char* z = "z";
|
||||||
|
|
||||||
|
static Node encode(SHVec3 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
node[z] = rhs.z;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec3& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
if (node[z].IsDefined())
|
||||||
|
rhs.z = node[z].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec2>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
|
||||||
|
static Node encode(SHVec2 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec2& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHCollider>
|
||||||
|
{
|
||||||
|
static constexpr const char* IsTrigger = "Is Trigger";
|
||||||
|
|
||||||
|
static constexpr const char* Type = "Type";
|
||||||
|
static constexpr const char* HalfExtents = "Half Extents";
|
||||||
|
static constexpr const char* Radius = "Radius";
|
||||||
|
|
||||||
|
static constexpr const char* Friction = "Friction";
|
||||||
|
static constexpr const char* Bounciness = "Bounciness";
|
||||||
|
static constexpr const char* Density = "Density";
|
||||||
|
static constexpr const char* PositionOffset = "Position Offset";
|
||||||
|
|
||||||
|
static Node encode(SHCollider& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
|
||||||
|
node[IsTrigger] = rhs.IsTrigger();
|
||||||
|
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
SHCollider::Type colliderType = rhs.GetType();
|
||||||
|
|
||||||
|
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||||
|
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX:
|
||||||
|
{
|
||||||
|
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
||||||
|
node[HalfExtents] = bb->GetHalfExtents();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::SPHERE:
|
||||||
|
{
|
||||||
|
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
||||||
|
node[Radius] = bs->GetRadius();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
|
||||||
|
node[Friction] = rhs.GetFriction();
|
||||||
|
node[Bounciness] = rhs.GetBounciness();
|
||||||
|
node[Density] = rhs.GetDensity();
|
||||||
|
node[PositionOffset] = rhs.GetPositionOffset();
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHCollider& rhs)
|
||||||
|
{
|
||||||
|
if (node[IsTrigger].IsDefined())
|
||||||
|
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||||
|
if (!node[Type].IsDefined())
|
||||||
|
return false;
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
bool ok;
|
||||||
|
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX:
|
||||||
|
{
|
||||||
|
if(node[HalfExtents].IsDefined())
|
||||||
|
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::SPHERE:
|
||||||
|
{
|
||||||
|
if(node[Radius].IsDefined())
|
||||||
|
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
if (node[Friction].IsDefined())
|
||||||
|
rhs.SetFriction(node[Friction].as<float>());
|
||||||
|
if (node[Bounciness].IsDefined())
|
||||||
|
rhs.SetBounciness(rhs.GetBounciness());
|
||||||
|
if (node[Density].IsDefined())
|
||||||
|
rhs.SetDensity(node[Density].as<float>());
|
||||||
|
if (node[PositionOffset].IsDefined())
|
||||||
|
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHColliderComponent>
|
||||||
|
{
|
||||||
|
static constexpr const char* Colliders = "Colliders";
|
||||||
|
static Node encode(SHColliderComponent& rhs)
|
||||||
|
{
|
||||||
|
Node node, collidersNode;
|
||||||
|
auto const& colliders = rhs.GetColliders();
|
||||||
|
int const numColliders = static_cast<int>(colliders.size());
|
||||||
|
for (int i = 0; i < numColliders; ++i)
|
||||||
|
{
|
||||||
|
auto& collider = rhs.GetCollider(i);
|
||||||
|
Node colliderNode = convert<SHCollider>::encode(collider);
|
||||||
|
if (colliderNode.IsDefined())
|
||||||
|
collidersNode[i] = colliderNode;
|
||||||
|
}
|
||||||
|
node[Colliders] = collidersNode;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHColliderComponent& rhs)
|
||||||
|
{
|
||||||
|
if (node[Colliders].IsDefined())
|
||||||
|
{
|
||||||
|
int numColliders{};
|
||||||
|
for (auto const& colliderNode : node[Colliders])
|
||||||
|
{
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
bool ok = false;
|
||||||
|
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
||||||
|
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<SHMaterial>
|
struct convert<SHMaterial>
|
||||||
{
|
{
|
||||||
|
@ -46,13 +271,13 @@ namespace YAML
|
||||||
propNode = rhs.GetProperty<int>(VARIABLE->offset);
|
propNode = rhs.GetProperty<int>(VARIABLE->offset);
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec2>(VARIABLE->offset));
|
propNode = rhs.GetProperty<SHVec2>(VARIABLE->offset);
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||||
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec3>(VARIABLE->offset));
|
propNode = rhs.GetProperty<SHVec3>(VARIABLE->offset);
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||||
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec4>(VARIABLE->offset));
|
propNode = rhs.GetProperty<SHVec4>(VARIABLE->offset);
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||||
default:
|
default:
|
||||||
|
@ -135,7 +360,7 @@ namespace YAML
|
||||||
return false;
|
return false;
|
||||||
rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline());
|
rhs.SetPipeline(gfxSystem->GetDefaultMaterial()->GetPipeline());
|
||||||
|
|
||||||
if (node[PROPS_YAML_TAG.data()])
|
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||||
{
|
{
|
||||||
// Loop through all properties
|
// Loop through all properties
|
||||||
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
||||||
|
@ -192,11 +417,11 @@ namespace YAML
|
||||||
}
|
}
|
||||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||||
{
|
{
|
||||||
if (node[MESH_YAML_TAG.data()])
|
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||||
{
|
{
|
||||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||||
}
|
}
|
||||||
if (node[MAT_YAML_TAG.data()])
|
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||||
{
|
{
|
||||||
// TODO: Convert Asset ID To Material HAndle
|
// TODO: Convert Asset ID To Material HAndle
|
||||||
// Temporarily, use default material
|
// Temporarily, use default material
|
||||||
|
@ -210,46 +435,34 @@ namespace YAML
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHSerializationHelper
|
struct SHSerializationHelper
|
||||||
{
|
{
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
||||||
static std::string SerializeComponentToString(ComponentType* component)
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
||||||
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static YAML::Node RTTRToNode(const rttr::variant& var)
|
static YAML::Node RTTRToNode(const rttr::variant& var)
|
||||||
{
|
{
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
auto varType = var.get_type();
|
auto varType = var.get_type();
|
||||||
|
if (varType.is_sequential_container())
|
||||||
|
{
|
||||||
|
for (auto const& elem : var.create_sequential_view())
|
||||||
|
{
|
||||||
|
node.push_back(RTTRToNode(elem));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (varType == rttr::type::get<SHVec4>())
|
if (varType == rttr::type::get<SHVec4>())
|
||||||
{
|
{
|
||||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
node = YAML::convert<SHVec4>::encode(var.convert<SHVec4>());
|
||||||
node["X"] = var.convert<SHVec4>().x;
|
|
||||||
node["Y"] = var.convert<SHVec4>().y;
|
|
||||||
node["Z"] = var.convert<SHVec4>().z;
|
|
||||||
node["W"] = var.convert<SHVec4>().w;
|
|
||||||
}
|
}
|
||||||
else if (varType == rttr::type::get<SHVec3>())
|
else if (varType == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
node = YAML::convert<SHVec3>::encode(var.convert<SHVec3>());
|
||||||
node["X"] = var.convert<SHVec3>().x;
|
|
||||||
node["Y"] = var.convert<SHVec3>().y;
|
|
||||||
node["Z"] = var.convert<SHVec3>().z;
|
|
||||||
}
|
}
|
||||||
else if (varType == rttr::type::get<SHVec2>())
|
else if (varType == rttr::type::get<SHVec2>())
|
||||||
{
|
{
|
||||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
node = YAML::convert<SHVec2>::encode(var.convert<SHVec2>());
|
||||||
node["X"] = var.convert<SHVec3>().x;
|
|
||||||
node["Y"] = var.convert<SHVec3>().y;
|
|
||||||
}
|
}
|
||||||
else if (varType.is_arithmetic())
|
else if (varType.is_arithmetic())
|
||||||
{
|
{
|
||||||
|
@ -300,7 +513,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto properties = var.get_type().get_properties();
|
auto properties = var.get_type().get_properties();
|
||||||
for (auto property : properties)
|
for (auto const& property : properties)
|
||||||
{
|
{
|
||||||
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
||||||
}
|
}
|
||||||
|
@ -308,6 +521,17 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static std::string SerializeComponentToString(ComponentType* component)
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
||||||
{
|
{
|
||||||
|
@ -327,15 +551,18 @@ namespace SHADE
|
||||||
auto propType = prop.get_type();
|
auto propType = prop.get_type();
|
||||||
if (propType == rttr::type::get<SHVec4>())
|
if (propType == rttr::type::get<SHVec4>())
|
||||||
{
|
{
|
||||||
prop.set_value(component, SHSerializationTools::YAMLToVec4(propertyNode));
|
SHVec4 vec = propertyNode.as<SHVec4>();
|
||||||
|
prop.set_value(component, vec);
|
||||||
}
|
}
|
||||||
else if (propType == rttr::type::get<SHVec3>())
|
else if (propType == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
prop.set_value(component, SHSerializationTools::YAMLToVec3(propertyNode));
|
SHVec3 vec = propertyNode.as<SHVec3>();
|
||||||
|
prop.set_value(component, vec);
|
||||||
}
|
}
|
||||||
else if (propType == rttr::type::get<SHVec2>())
|
else if (propType == rttr::type::get<SHVec2>())
|
||||||
{
|
{
|
||||||
prop.set_value(component, SHSerializationTools::YAMLToVec2(propertyNode));
|
SHVec2 vec = propertyNode.as<SHVec2>();
|
||||||
|
prop.set_value(component, vec);
|
||||||
}
|
}
|
||||||
else if (propType.is_arithmetic())
|
else if (propType.is_arithmetic())
|
||||||
{
|
{
|
||||||
|
@ -371,9 +598,10 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto properties = propType.get_properties();
|
auto properties = propType.get_properties();
|
||||||
for (auto property : properties)
|
for (auto const& property : properties)
|
||||||
{
|
{
|
||||||
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
if(propertyNode[property.get_name().data()].IsDefined())
|
||||||
|
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,7 +609,7 @@ namespace SHADE
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
{
|
{
|
||||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
if (componentsNode.IsNull() && !component)
|
if (componentsNode.IsNull() && !component)
|
||||||
return;
|
return;
|
||||||
auto rttrType = rttr::type::get<ComponentType>();
|
auto rttrType = rttr::type::get<ComponentType>();
|
||||||
|
@ -406,7 +634,7 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
auto rttrType = rttr::type::get<ComponentType>();
|
auto rttrType = rttr::type::get<ComponentType>();
|
||||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||||
if (componentsNode.IsNull())
|
if (!componentNode.IsDefined())
|
||||||
return;
|
return;
|
||||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
YAML::convert<ComponentType>::decode(componentNode, *component);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue