Deserialization flow is now as follows:
Create entities and components >> Fetch Assets needed >> Load assets needed >> Initialize entities Some other bug fixes
This commit is contained in:
parent
4ee0294977
commit
1267442210
|
@ -32,7 +32,7 @@
|
|||
Scale: {x: 49.4798889, y: 0.5, z: 17.5}
|
||||
Renderable Component:
|
||||
Mesh: 80365422
|
||||
Material: 126974645
|
||||
Material: 0
|
||||
RigidBody Component:
|
||||
Type: Static
|
||||
Mass: 1
|
||||
|
|
|
@ -189,12 +189,17 @@ namespace SHADE
|
|||
switch (file.assetMeta->type)
|
||||
{
|
||||
case AssetType::INVALID: break;
|
||||
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||
case AssetType::SHADER: break;
|
||||
case AssetType::SHADER_BUILT_IN: break;
|
||||
case AssetType::TEXTURE: break;
|
||||
case AssetType::MESH: break;
|
||||
case AssetType::SCENE:
|
||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||
{
|
||||
editor->LoadScene(file.assetMeta->id);
|
||||
}
|
||||
break;
|
||||
case AssetType::PREFAB: break;
|
||||
case AssetType::MATERIAL:
|
||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||
{
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
|
||||
namespace SHADE
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
||||
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -68,6 +68,10 @@ namespace SHADE
|
|||
return;
|
||||
|
||||
batch->Remove(renderable);
|
||||
|
||||
// If batch is empty, remove batch
|
||||
if (batch->IsEmpty())
|
||||
batches.erase(batch);
|
||||
}
|
||||
|
||||
void SHSuperBatch::Clear() noexcept
|
||||
|
|
|
@ -270,7 +270,15 @@ namespace SHADE
|
|||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||
|
||||
// Create default materials
|
||||
std::array<SHTexture::PixelChannel, 4> defaultTexture = { 255, 255, 255, 255 };
|
||||
std::vector<uint32_t> mipOffsets{};
|
||||
mipOffsets.push_back(0);
|
||||
auto tex = AddTexture(4, defaultTexture.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets);
|
||||
BuildTextures();
|
||||
|
||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||
defaultMaterial->SetProperty("data.textureIndex", tex->TextureArrayIndex);
|
||||
|
||||
|
||||
// Create debug draw pipeline
|
||||
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||
|
|
|
@ -156,14 +156,15 @@ namespace SHADE
|
|||
/* Build Descriptor Set with all the Textures only if there are textures */
|
||||
if (!texOrder.empty())
|
||||
{
|
||||
if (!texDescriptors)
|
||||
if (texDescriptors)
|
||||
{
|
||||
texDescriptors = descPool->Allocate
|
||||
(
|
||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||
{ static_cast<uint32_t>(texOrder.size()) }
|
||||
);
|
||||
texDescriptors.Free();
|
||||
}
|
||||
texDescriptors = descPool->Allocate
|
||||
(
|
||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||
{ static_cast<uint32_t>(texOrder.size()) }
|
||||
);
|
||||
texDescriptors->ModifyWriteDescImage
|
||||
(
|
||||
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||
|
|
|
@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Serialization/SHSerializationHelper.hpp"
|
||||
#include "Serialization/SHYAMLConverters.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "SHSerializationHelper.hpp"
|
||||
#include "SHSerialization.h"
|
||||
#include "SHSerializationHelper.hpp"
|
||||
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
|
@ -118,8 +118,15 @@ namespace SHADE
|
|||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||
return NewSceneName.data();
|
||||
}
|
||||
//Initialize Entity
|
||||
auto entityVecIt = createdEntities.begin();
|
||||
AssetQueue assetQueue;
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], *entityVecIt, assetQueue);
|
||||
}
|
||||
LoadAssetsFromAssetQueue(assetQueue);
|
||||
//Initialize Entity
|
||||
entityVecIt = createdEntities.begin();
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
InitializeEntity(*it, *entityVecIt++);
|
||||
|
@ -256,6 +263,33 @@ namespace SHADE
|
|||
return componentIDList;
|
||||
}
|
||||
|
||||
void SHSerialization::LoadAssetsFromAssetQueue(AssetQueue& assetQueue)
|
||||
{
|
||||
for (auto& [assetId, assetType] : assetQueue)
|
||||
{
|
||||
switch(assetType)
|
||||
{
|
||||
case AssetType::INVALID: break;
|
||||
case AssetType::SHADER: break;
|
||||
case AssetType::SHADER_BUILT_IN: break;
|
||||
case AssetType::TEXTURE:
|
||||
SHResourceManager::LoadOrGet<SHTexture>(assetId);
|
||||
break;
|
||||
case AssetType::MESH:
|
||||
SHResourceManager::LoadOrGet<SHMesh>(assetId);
|
||||
break;
|
||||
case AssetType::SCENE: break;
|
||||
case AssetType::PREFAB: break;
|
||||
case AssetType::MATERIAL:
|
||||
SHResourceManager::LoadOrGet<SHMaterial>(assetId);
|
||||
break;
|
||||
case AssetType::MAX_COUNT: break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}
|
||||
|
||||
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||
{
|
||||
auto const componentsNode = entityNode[ComponentsNode];
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#include <ECS_Base/Components/SHComponent.h>
|
||||
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include <Assets/SHAssetMacros.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
@ -42,6 +44,8 @@ namespace SHADE
|
|||
static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept;
|
||||
|
||||
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||
|
||||
static void LoadAssetsFromAssetQueue(std::unordered_map<AssetID, AssetType>& assetQueue);
|
||||
private:
|
||||
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||
|
||||
|
|
|
@ -1,329 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "SHYAMLConverters.h"
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
||||
#include <rttr/registration>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "SHSerializationTools.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Tools/SHLog.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
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++));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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";
|
||||
|
||||
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Retrieve Subpass
|
||||
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Retrieve
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
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));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
using AssetQueue = std::unordered_map<AssetID, AssetType>;
|
||||
struct SHSerializationHelper
|
||||
{
|
||||
|
||||
|
@ -517,18 +208,73 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static YAML::Node GetComponentNode(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()];
|
||||
if (!componentNode.IsDefined())
|
||||
return {};
|
||||
return componentNode;
|
||||
}
|
||||
|
||||
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()];
|
||||
if (!componentNode.IsDefined())
|
||||
return;
|
||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
||||
|
||||
YAML::convert<ComponentType>::decode(GetComponentNode<ComponentType>(componentsNode, eid), *component);
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void FetchAssetsFromComponent(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
static void FetchAssetsFromComponent<SHRenderable>(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||
{
|
||||
auto node = GetComponentNode<SHRenderable>(componentsNode, eid);
|
||||
if(!node.IsDefined())
|
||||
return;
|
||||
if (auto const& meshNode = node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()]; meshNode.IsDefined())
|
||||
{
|
||||
assetQueue.insert({meshNode.as<AssetID>(), AssetType::MESH});
|
||||
//SHResourceManager::LoadOrGet<SHMesh>(node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()].as<AssetID>());
|
||||
}
|
||||
if (auto const& matNode = node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()]; matNode.IsDefined())
|
||||
{
|
||||
auto const matAsset = SHAssetManager::GetData<SHMaterialAsset>(matNode.as<AssetID>());
|
||||
if(matAsset)
|
||||
{
|
||||
SHMaterialSpec spec;
|
||||
YAML::convert<SHMaterialSpec>::decode(*YAML::Load(matAsset->data).begin(), spec);
|
||||
if(spec.properties.IsDefined())
|
||||
{
|
||||
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(spec.fragShader);
|
||||
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
|
||||
/*int const varCount = static_cast<int>(interface->GetVariableCount());
|
||||
|
||||
for (int i = 0; i < varCount; ++i)
|
||||
{
|
||||
auto variable = interface->GetVariable(i);
|
||||
if(variable->type != SHShaderBlockInterface::Variable::Type::INT)
|
||||
return;
|
||||
const std::string& VAR_NAME = interface->GetVariableName(i);
|
||||
if(VAR_NAME.empty())
|
||||
continue;
|
||||
assetQueue.insert({matNode.as<AssetID>(), AssetType::TEXTURE});
|
||||
}*/
|
||||
}
|
||||
}
|
||||
assetQueue.insert({matNode.as<AssetID>(), AssetType::MATERIAL});
|
||||
//SHResourceManager::LoadOrGet<SHMaterial>(node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()].as<AssetID>());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
#pragma once
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||
#include "Math/Geometry/SHBoundingBox.h"
|
||||
#include "Math/Geometry/SHBoundingSphere.h"
|
||||
#include "Physics/SHCollider.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||
#include "SHSerializationTools.h"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
namespace YAML
|
||||
{
|
||||
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++));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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";
|
||||
|
||||
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||
{
|
||||
YAML::Node node;
|
||||
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||
{
|
||||
// Retrieve Shader Asset IDs
|
||||
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||
|
||||
// Retrieve Subpass
|
||||
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||
|
||||
// Retrieve
|
||||
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||
return node;
|
||||
}
|
||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||
{
|
||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||
}
|
||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||
{
|
||||
// Temporarily, use default material
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (!gfxSystem)
|
||||
return false;
|
||||
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));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue