2022-09-26 21:08:59 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <yaml-cpp/yaml.h>
|
2022-10-21 18:36:56 +08:00
|
|
|
#include "ECS_Base/Components/SHComponent.h"
|
2022-09-26 21:08:59 +08:00
|
|
|
|
|
|
|
#include <rttr/registration>
|
|
|
|
|
2022-10-01 23:43:00 +08:00
|
|
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
2022-09-27 07:03:31 +08:00
|
|
|
#include "Math/Vector/SHVec2.h"
|
|
|
|
#include "Math/Vector/SHVec3.h"
|
|
|
|
#include "Math/Vector/SHVec4.h"
|
2022-10-21 18:36:56 +08:00
|
|
|
#include "Resource/SHResourceManager.h"
|
|
|
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
2022-10-22 19:38:02 +08:00
|
|
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
2022-10-31 17:47:38 +08:00
|
|
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
2022-10-22 19:38:02 +08:00
|
|
|
#include "SHSerializationTools.h"
|
2022-10-25 08:42:51 +08:00
|
|
|
#include "Physics/Components/SHColliderComponent.h"
|
2022-10-31 17:47:38 +08:00
|
|
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
|
|
|
#include "Tools/SHLog.h"
|
2022-10-21 18:36:56 +08:00
|
|
|
|
|
|
|
namespace YAML
|
|
|
|
{
|
|
|
|
using namespace SHADE;
|
2022-10-25 08:42:51 +08:00
|
|
|
|
2022-10-28 13:17:22 +08:00
|
|
|
template<>
|
2022-10-25 08:42:51 +08:00
|
|
|
struct convert<SHVec4>
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
2022-10-25 08:42:51 +08:00
|
|
|
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)
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
2022-10-25 08:42:51 +08:00
|
|
|
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)
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[x].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.x = node[x].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[y].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.y = node[y].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[z].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.z = node[z].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[w].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.w = node[w].as<float>();
|
|
|
|
return true;
|
2022-09-26 21:08:59 +08:00
|
|
|
}
|
2022-10-25 08:42:51 +08:00
|
|
|
};
|
2022-09-26 21:08:59 +08:00
|
|
|
|
2022-10-25 08:42:51 +08:00
|
|
|
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)
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[x].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.x = node[x].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[y].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.y = node[y].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[z].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.z = node[z].as<float>();
|
|
|
|
return true;
|
2022-09-26 21:08:59 +08:00
|
|
|
}
|
2022-10-25 08:42:51 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[x].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.x = node[x].as<float>();
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[y].IsDefined())
|
2022-10-25 08:42:51 +08:00
|
|
|
rhs.y = node[y].as<float>();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
2022-10-25 15:09:45 +08:00
|
|
|
|
|
|
|
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;
|
2022-10-30 11:26:23 +08:00
|
|
|
|
2022-10-25 15:09:45 +08:00
|
|
|
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)
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[IsTrigger].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
2022-10-30 11:26:23 +08:00
|
|
|
if (!node[Type].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
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:
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if(node[HalfExtents].IsDefined())
|
|
|
|
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
2022-10-25 15:09:45 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SHCollider::Type::SPHERE:
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if(node[Radius].IsDefined())
|
|
|
|
rhs.SetBoundingSphere(node[Radius].as<float>());
|
2022-10-25 15:09:45 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SHCollider::Type::CAPSULE: break;
|
|
|
|
default:;
|
|
|
|
}
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[Friction].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
rhs.SetFriction(node[Friction].as<float>());
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[Bounciness].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
rhs.SetBounciness(rhs.GetBounciness());
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[Density].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
rhs.SetDensity(node[Density].as<float>());
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[PositionOffset].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
2022-10-28 19:39:39 +08:00
|
|
|
|
2022-10-25 15:09:45 +08:00
|
|
|
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)
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[Colliders].IsDefined())
|
2022-10-25 15:09:45 +08:00
|
|
|
{
|
|
|
|
int numColliders{};
|
|
|
|
for (auto const& colliderNode : node[Colliders])
|
|
|
|
{
|
|
|
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
|
|
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
2022-10-30 11:26:23 +08:00
|
|
|
bool ok = false;
|
2022-10-25 15:09:45 +08:00
|
|
|
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
|
|
|
if (!ok)
|
|
|
|
return false;
|
2022-10-28 19:39:39 +08:00
|
|
|
|
2022-10-25 15:09:45 +08:00
|
|
|
switch (colliderType)
|
|
|
|
{
|
|
|
|
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
|
|
|
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
|
|
|
case SHCollider::Type::CAPSULE: break;
|
|
|
|
default:;
|
|
|
|
}
|
2022-10-28 19:39:39 +08:00
|
|
|
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
2022-10-25 15:09:45 +08:00
|
|
|
}
|
|
|
|
}
|
2022-10-30 23:15:41 +08:00
|
|
|
return true;
|
2022-10-25 15:09:45 +08:00
|
|
|
}
|
|
|
|
};
|
2022-10-28 13:17:22 +08:00
|
|
|
|
2022-10-22 19:38:02 +08:00
|
|
|
template<>
|
|
|
|
struct convert<SHMaterial>
|
|
|
|
{
|
|
|
|
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
|
|
|
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
2022-10-22 21:36:02 +08:00
|
|
|
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
2022-10-22 19:38:02 +08:00
|
|
|
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
|
|
|
|
|
|
|
static YAML::Node encode(SHMaterial const& rhs)
|
|
|
|
{
|
|
|
|
// Write Properties
|
|
|
|
YAML::Node propertiesNode;
|
|
|
|
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
|
|
|
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
|
|
|
{
|
|
|
|
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
|
|
|
if (!VARIABLE)
|
|
|
|
break;
|
|
|
|
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
|
|
|
YAML::Node propNode;
|
|
|
|
switch (VARIABLE->type)
|
|
|
|
{
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
|
|
|
propNode = rhs.GetProperty<float>(VARIABLE->offset);
|
|
|
|
break;
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
|
|
|
propNode = rhs.GetProperty<int>(VARIABLE->offset);
|
|
|
|
break;
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
2022-10-28 19:39:39 +08:00
|
|
|
propNode = rhs.GetProperty<SHVec2>(VARIABLE->offset);
|
2022-10-22 19:38:02 +08:00
|
|
|
break;
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
2022-10-28 19:39:39 +08:00
|
|
|
propNode = rhs.GetProperty<SHVec3>(VARIABLE->offset);
|
2022-10-22 19:38:02 +08:00
|
|
|
break;
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
2022-10-28 19:39:39 +08:00
|
|
|
propNode = rhs.GetProperty<SHVec4>(VARIABLE->offset);
|
2022-10-22 19:38:02 +08:00
|
|
|
break;
|
|
|
|
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
propertiesNode[VAR_NAME.data()] = propNode;
|
|
|
|
}
|
|
|
|
|
2022-10-22 21:36:02 +08:00
|
|
|
// Get Shader Handles
|
|
|
|
const auto& SHADERS = rhs.GetPipeline()->GetPipelineLayout()->GetShaderModules();
|
|
|
|
Handle<SHVkShaderModule> vertexShader, fragShader;
|
|
|
|
for (const auto& shader : SHADERS)
|
|
|
|
{
|
|
|
|
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
|
|
|
|
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
|
|
|
|
vertexShader = shader;
|
|
|
|
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
|
|
|
|
fragShader = shader;
|
|
|
|
}
|
|
|
|
|
2022-10-22 19:38:02 +08:00
|
|
|
// Write Material
|
|
|
|
YAML::Node node;
|
|
|
|
|
2022-10-29 01:54:43 +08:00
|
|
|
node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
|
|
|
|
node[FRAG_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
|
|
|
|
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
2022-10-22 21:36:02 +08:00
|
|
|
node[PROPS_YAML_TAG.data()] = propertiesNode;
|
2022-10-22 19:38:02 +08:00
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
2022-10-31 17:47:38 +08:00
|
|
|
};
|
2022-10-22 21:36:02 +08:00
|
|
|
|
2022-10-31 17:47:38 +08:00
|
|
|
template<>
|
|
|
|
struct convert<SHMaterialSpec>
|
|
|
|
{
|
|
|
|
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
|
|
|
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
|
|
|
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
|
|
|
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
2022-10-22 21:36:02 +08:00
|
|
|
|
2022-10-31 17:47:38 +08:00
|
|
|
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
|
|
|
{
|
|
|
|
// Retrieve Shader Asset IDs
|
|
|
|
if (!node[VERT_SHADER_YAML_TAG.data()])
|
|
|
|
return false;
|
|
|
|
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
|
|
|
if (!node[FRAG_SHADER_YAML_TAG.data()])
|
|
|
|
return false;
|
|
|
|
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
|
|
|
|
|
|
|
// Retrieve Subpass
|
|
|
|
if (!node[SUBPASS_YAML_TAG.data()])
|
|
|
|
return false;
|
|
|
|
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
|
|
|
|
|
|
|
// Retrieve
|
|
|
|
if (!node[PROPS_YAML_TAG.data()])
|
|
|
|
return false;
|
|
|
|
rhs.properties = node[PROPS_YAML_TAG.data()];
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2022-10-22 19:38:02 +08:00
|
|
|
};
|
|
|
|
|
2022-10-21 18:36:56 +08:00
|
|
|
template<>
|
|
|
|
struct convert<SHRenderable>
|
|
|
|
{
|
|
|
|
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
|
|
|
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
|
|
|
|
|
|
|
static YAML::Node encode(SHRenderable const& rhs)
|
|
|
|
{
|
|
|
|
YAML::Node node;
|
2022-10-27 23:18:02 +08:00
|
|
|
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
2022-10-31 17:47:38 +08:00
|
|
|
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
2022-10-21 18:36:56 +08:00
|
|
|
return node;
|
|
|
|
}
|
|
|
|
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[MESH_YAML_TAG.data()].IsDefined())
|
2022-10-21 18:36:56 +08:00
|
|
|
{
|
2022-10-27 23:18:02 +08:00
|
|
|
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
2022-10-21 18:36:56 +08:00
|
|
|
}
|
2022-10-30 11:26:23 +08:00
|
|
|
if (node[MAT_YAML_TAG.data()].IsDefined())
|
2022-10-21 18:36:56 +08:00
|
|
|
{
|
2022-10-27 23:18:02 +08:00
|
|
|
// Temporarily, use default material
|
|
|
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
|
|
|
if (!gfxSystem)
|
|
|
|
return false;
|
2022-10-31 17:47:38 +08:00
|
|
|
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
|
|
|
if (!baseMat)
|
|
|
|
{
|
|
|
|
baseMat = gfxSystem->GetDefaultMaterial();
|
|
|
|
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
|
|
|
}
|
|
|
|
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
2022-10-21 18:36:56 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-09-26 21:08:59 +08:00
|
|
|
namespace SHADE
|
|
|
|
{
|
2022-09-26 23:51:20 +08:00
|
|
|
struct SHSerializationHelper
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
static YAML::Node RTTRToNode(const rttr::variant& var)
|
|
|
|
{
|
|
|
|
YAML::Node node;
|
|
|
|
auto varType = var.get_type();
|
2022-10-25 15:09:45 +08:00
|
|
|
if (varType.is_sequential_container())
|
2022-10-25 08:42:51 +08:00
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
for (auto const& elem : var.create_sequential_view())
|
2022-10-25 08:42:51 +08:00
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
node.push_back(RTTRToNode(elem));
|
2022-10-25 08:42:51 +08:00
|
|
|
}
|
|
|
|
}
|
2022-10-01 23:43:00 +08:00
|
|
|
if (varType == rttr::type::get<SHVec4>())
|
2022-09-27 07:03:31 +08:00
|
|
|
{
|
2022-10-25 08:42:51 +08:00
|
|
|
node = YAML::convert<SHVec4>::encode(var.convert<SHVec4>());
|
2022-09-27 07:03:31 +08:00
|
|
|
}
|
2022-10-01 23:43:00 +08:00
|
|
|
else if (varType == rttr::type::get<SHVec3>())
|
2022-09-27 07:03:31 +08:00
|
|
|
{
|
2022-10-25 08:42:51 +08:00
|
|
|
node = YAML::convert<SHVec3>::encode(var.convert<SHVec3>());
|
2022-09-27 07:03:31 +08:00
|
|
|
}
|
2022-10-01 23:43:00 +08:00
|
|
|
else if (varType == rttr::type::get<SHVec2>())
|
2022-09-27 07:03:31 +08:00
|
|
|
{
|
2022-10-25 08:42:51 +08:00
|
|
|
node = YAML::convert<SHVec2>::encode(var.convert<SHVec2>());
|
2022-09-27 07:03:31 +08:00
|
|
|
}
|
2022-10-01 23:43:00 +08:00
|
|
|
else if (varType.is_arithmetic())
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
if (varType == rttr::type::get<bool>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_bool();
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<int8_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_int8(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<int16_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_int16(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<int32_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_int32(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<int64_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_int64(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<uint8_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_uint8(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<uint16_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_uint16(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<uint32_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_uint32(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<uint64_t>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_uint64(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<float>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_float(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
else if (varType == rttr::type::get<double>())
|
2022-10-01 23:43:00 +08:00
|
|
|
node = var.to_double(&ok);
|
2022-09-26 21:08:59 +08:00
|
|
|
//else if (varType == rttr::type::get<char>()) //same as uint8_t
|
|
|
|
// node = var.to_uint8();
|
|
|
|
}
|
|
|
|
else if (varType.is_enumeration())
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
auto result = var.to_string(&ok);
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
node = var.to_string();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-10-01 23:43:00 +08:00
|
|
|
ok = false;
|
|
|
|
auto value = var.to_uint64(&ok);
|
|
|
|
if (ok)
|
|
|
|
node = value;
|
|
|
|
else
|
|
|
|
node = YAML::Null;
|
2022-09-26 21:08:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto properties = var.get_type().get_properties();
|
2022-10-25 15:09:45 +08:00
|
|
|
for (auto const& property : properties)
|
2022-09-26 21:08:59 +08:00
|
|
|
{
|
|
|
|
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
2022-10-25 15:09:45 +08:00
|
|
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
2022-10-25 08:42:51 +08:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-10-01 23:43:00 +08:00
|
|
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
2022-09-26 21:08:59 +08:00
|
|
|
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
|
|
|
{
|
|
|
|
YAML::Node node{};
|
2022-10-01 23:43:00 +08:00
|
|
|
if (!component)
|
|
|
|
return node;
|
2022-09-26 21:08:59 +08:00
|
|
|
|
|
|
|
auto componentType = rttr::type::get<ComponentType>();
|
2022-09-26 23:51:20 +08:00
|
|
|
node = RTTRToNode(*component);
|
2022-09-26 21:08:59 +08:00
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
2022-10-01 23:43:00 +08:00
|
|
|
|
|
|
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
|
|
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
|
|
|
|
{
|
|
|
|
auto propType = prop.get_type();
|
|
|
|
if (propType == rttr::type::get<SHVec4>())
|
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
SHVec4 vec = propertyNode.as<SHVec4>();
|
2022-10-01 23:43:00 +08:00
|
|
|
prop.set_value(component, vec);
|
|
|
|
}
|
|
|
|
else if (propType == rttr::type::get<SHVec3>())
|
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
SHVec3 vec = propertyNode.as<SHVec3>();
|
2022-10-01 23:43:00 +08:00
|
|
|
prop.set_value(component, vec);
|
|
|
|
}
|
|
|
|
else if (propType == rttr::type::get<SHVec2>())
|
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
SHVec2 vec = propertyNode.as<SHVec2>();
|
2022-10-01 23:43:00 +08:00
|
|
|
prop.set_value(component, vec);
|
|
|
|
}
|
|
|
|
else if (propType.is_arithmetic())
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
if (propType == rttr::type::get<bool>())
|
|
|
|
prop.set_value(component, propertyNode.as<bool>());
|
|
|
|
else if (propType == rttr::type::get<int8_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<int8_t>());
|
|
|
|
else if (propType == rttr::type::get<int16_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<int16_t>());
|
|
|
|
else if (propType == rttr::type::get<int32_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<int32_t>());
|
|
|
|
else if (propType == rttr::type::get<int64_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<int64_t>());
|
|
|
|
else if (propType == rttr::type::get<uint8_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<uint8_t>());
|
|
|
|
else if (propType == rttr::type::get<uint16_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<uint16_t>());
|
|
|
|
else if (propType == rttr::type::get<uint32_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<uint32_t>());
|
|
|
|
else if (propType == rttr::type::get<uint64_t>())
|
|
|
|
prop.set_value(component, propertyNode.as<uint64_t>());
|
|
|
|
else if (propType == rttr::type::get<float>())
|
|
|
|
prop.set_value(component, propertyNode.as<float>());
|
|
|
|
else if (propType == rttr::type::get<double>())
|
|
|
|
prop.set_value(component, propertyNode.as<double>());
|
|
|
|
}
|
|
|
|
else if (propType.is_enumeration())
|
|
|
|
{
|
|
|
|
auto enumAlign = prop.get_enumeration();
|
|
|
|
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto properties = propType.get_properties();
|
2022-10-25 15:09:45 +08:00
|
|
|
for (auto const& property : properties)
|
2022-10-01 23:43:00 +08:00
|
|
|
{
|
2022-10-30 11:26:23 +08:00
|
|
|
if(propertyNode[property.get_name().data()].IsDefined())
|
|
|
|
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
2022-10-01 23:43:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
2022-10-01 23:43:00 +08:00
|
|
|
if (componentsNode.IsNull() && !component)
|
|
|
|
return;
|
|
|
|
auto rttrType = rttr::type::get<ComponentType>();
|
|
|
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
2022-10-28 17:58:16 +08:00
|
|
|
if(!componentNode.IsDefined())
|
2022-10-01 23:43:00 +08:00
|
|
|
return;
|
|
|
|
auto properties = rttrType.get_properties();
|
|
|
|
for (auto const& prop : properties)
|
|
|
|
{
|
2022-10-25 15:09:45 +08:00
|
|
|
if (componentNode[prop.get_name().data()].IsDefined())
|
2022-10-01 23:43:00 +08:00
|
|
|
{
|
|
|
|
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-27 19:31:00 +08:00
|
|
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
|
|
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
|
|
|
|
{
|
|
|
|
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
|
|
|
if (componentsNode.IsNull() && !component)
|
|
|
|
return;
|
|
|
|
auto rttrType = rttr::type::get<ComponentType>();
|
|
|
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
2022-10-30 11:26:23 +08:00
|
|
|
if (!componentNode.IsDefined())
|
2022-10-27 19:31:00 +08:00
|
|
|
return;
|
|
|
|
YAML::convert<ComponentType>::decode(componentNode, *component);
|
|
|
|
}
|
|
|
|
|
2022-09-26 23:51:20 +08:00
|
|
|
};
|
2022-09-27 07:03:31 +08:00
|
|
|
}
|