Serialize/Deserialize SHCollider & SHColliderComponent
This commit is contained in:
parent
f64f13521b
commit
8466309e2f
|
@ -48,15 +48,28 @@ namespace SHADE
|
|||
|
||||
if (Begin())
|
||||
{
|
||||
if(skipFrame)
|
||||
{
|
||||
ImGui::End();
|
||||
skipFrame = false;
|
||||
return;
|
||||
}
|
||||
DrawMenuBar();
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
if (const auto root = sceneGraph.GetRoot())
|
||||
{
|
||||
auto const& children = root->GetChildren();
|
||||
|
||||
for (const auto child : children)
|
||||
{
|
||||
if(child)
|
||||
RecursivelyDrawEntityNode(child);
|
||||
if(skipFrame)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -120,8 +133,10 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||
{
|
||||
if(currentNode == nullptr)
|
||||
return {};
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
//Get node data (Children, eid, selected)
|
||||
|
@ -193,10 +208,16 @@ namespace SHADE
|
|||
if(ImGui::Selectable("Paste"))
|
||||
{
|
||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
||||
skipFrame = true;
|
||||
ImGui::EndPopup();
|
||||
if(isNodeOpen)
|
||||
ImGui::TreePop();
|
||||
return nodeRect;
|
||||
}
|
||||
if(ImGui::Selectable("Paste as Child"))
|
||||
{
|
||||
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
||||
skipFrame = true;
|
||||
}
|
||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||
{
|
||||
|
|
|
@ -26,10 +26,12 @@ namespace SHADE
|
|||
void SetScrollTo(EntityID eid);
|
||||
private:
|
||||
void DrawMenuBar() const noexcept;
|
||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||
|
||||
bool skipFrame = false;
|
||||
std::string filter;
|
||||
bool isAnyNodeSelected = false;
|
||||
EntityID scrollTo = MAX_EID;
|
||||
|
|
|
@ -85,6 +85,8 @@ namespace SHADE
|
|||
// Deserialise scripts
|
||||
if (node[ScriptsNode])
|
||||
SHSystemManager::GetSystem<SHScriptEngine>()->DeserialiseScripts(eid, node[ScriptsNode]);
|
||||
|
||||
return eid;
|
||||
}
|
||||
|
||||
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
||||
|
@ -192,9 +194,9 @@ namespace SHADE
|
|||
{
|
||||
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
|
||||
}
|
||||
if (const auto collisionComp = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||
if (auto collisionComp = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||
{
|
||||
components[rttr::type::get<SHColliderComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(collisionComp);
|
||||
components[rttr::type::get<SHColliderComponent>().get_name().data()] = YAML::convert<SHColliderComponent>::encode(*collisionComp);
|
||||
}
|
||||
node[ComponentsNode] = components;
|
||||
|
||||
|
@ -254,6 +256,10 @@ namespace SHADE
|
|||
if (id.has_value())
|
||||
componentIDList.push_back(id.value());
|
||||
|
||||
id = GetComponentID<SHColliderComponent>(componentsNode);
|
||||
if(id.has_value())
|
||||
componentIDList.push_back(id.value());
|
||||
|
||||
return componentIDList;
|
||||
}
|
||||
|
||||
|
@ -263,5 +269,7 @@ namespace SHADE
|
|||
if (!componentsNode)
|
||||
return;
|
||||
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
||||
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
|
||||
SHSerializationHelper::InitializeComponentFromNodeData<SHColliderComponent>(componentsNode, eid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,155 @@ namespace YAML
|
|||
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])
|
||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||
if (!node[Type])
|
||||
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(auto const bb = dynamic_cast<SHBoundingBox*>(rhs.GetShape()); bb)
|
||||
{
|
||||
if (node[HalfExtents])
|
||||
{
|
||||
bb->SetHalfExtents(node[HalfExtents].as<SHVec3>());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::SPHERE:
|
||||
{
|
||||
if(auto const bs = dynamic_cast<SHBoundingSphere*>(rhs.GetShape()); bs)
|
||||
{
|
||||
if (node[Radius])
|
||||
{
|
||||
bs->SetRadius(node[Radius].as<float>());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SHCollider::Type::CAPSULE: break;
|
||||
default:;
|
||||
}
|
||||
if (node[Friction])
|
||||
rhs.SetFriction(node[Friction].as<float>());
|
||||
if (node[Bounciness])
|
||||
rhs.SetBounciness(rhs.GetBounciness());
|
||||
if (node[Density])
|
||||
rhs.SetDensity(node[Density].as<float>());
|
||||
if (node[PositionOffset])
|
||||
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.IsNull())
|
||||
return false;
|
||||
if (node[Colliders])
|
||||
{
|
||||
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;
|
||||
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:;
|
||||
}
|
||||
rhs.GetCollider(numColliders++) = colliderNode.as<SHCollider>();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace SHADE
|
||||
|
@ -178,7 +327,7 @@ namespace SHADE
|
|||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
@ -216,17 +365,17 @@ namespace SHADE
|
|||
auto propType = prop.get_type();
|
||||
if (propType == rttr::type::get<SHVec4>())
|
||||
{
|
||||
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() };
|
||||
SHVec4 vec = propertyNode.as<SHVec4>();
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType == rttr::type::get<SHVec3>())
|
||||
{
|
||||
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() };
|
||||
SHVec3 vec = propertyNode.as<SHVec3>();
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType == rttr::type::get<SHVec2>())
|
||||
{
|
||||
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() };
|
||||
SHVec2 vec = propertyNode.as<SHVec2>();
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType.is_arithmetic())
|
||||
|
@ -263,7 +412,7 @@ namespace SHADE
|
|||
else
|
||||
{
|
||||
auto properties = propType.get_properties();
|
||||
for (auto property : properties)
|
||||
for (auto const& property : properties)
|
||||
{
|
||||
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||
}
|
||||
|
@ -273,7 +422,7 @@ namespace SHADE
|
|||
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)
|
||||
{
|
||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
if (componentsNode.IsNull() && !component)
|
||||
return;
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
|
@ -283,12 +432,26 @@ namespace SHADE
|
|||
auto properties = rttrType.get_properties();
|
||||
for (auto const& prop : properties)
|
||||
{
|
||||
if (componentNode[prop.get_name().data()])
|
||||
|
||||
if (componentNode[prop.get_name().data()].IsDefined())
|
||||
{
|
||||
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void InitializeComponentFromNodeData(YAML::Node const& componentsNode, EntityID const& eid)
|
||||
{
|
||||
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
if (componentsNode.IsNull() && !component)
|
||||
return;
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||
if (componentsNode.IsNull())
|
||||
return;
|
||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue