From 3658144a15a1ac6a682a36b9718a8dcab32a5fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Tue, 12 Mar 2024 22:05:12 +0100 Subject: [PATCH] Implemented more serializers --- Volt/Volt/src/Volt/Animation/BlendSpace.h | 1 + Volt/Volt/src/Volt/Asset/AssetManager.cpp | 6 +- .../ImportersNew/BehaviourTreeSerializer.cpp | 237 ++++++++++++++++++ .../ImportersNew/BehaviourTreeSerializer.h | 13 + .../ImportersNew/BlendSpaceSerializer.cpp | 71 ++++++ .../Asset/ImportersNew/BlendSpaceSerializer.h | 13 + .../Asset/ImportersNew/MeshSerializer.cpp | 3 +- .../PostProcessingStackSerializer.cpp | 79 ++++++ .../PostProcessingStackSerializer.h | 13 + .../Asset/Rendering/PostProcessingStack.h | 1 + .../src/Volt/BehaviorTree/NodeManager.cpp | 4 +- Volt/Volt/src/Volt/BehaviorTree/NodeManager.h | 3 +- 12 files changed, 436 insertions(+), 8 deletions(-) create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.h create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.h create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.h diff --git a/Volt/Volt/src/Volt/Animation/BlendSpace.h b/Volt/Volt/src/Volt/Animation/BlendSpace.h index a2e115bd2..c6f5ab74b 100644 --- a/Volt/Volt/src/Volt/Animation/BlendSpace.h +++ b/Volt/Volt/src/Volt/Animation/BlendSpace.h @@ -32,6 +32,7 @@ namespace Volt private: friend class BlendSpaceImporter; + friend class BlendSpaceSerializer; BlendSpaceDimension myDimension = BlendSpaceDimension::OneD; diff --git a/Volt/Volt/src/Volt/Asset/AssetManager.cpp b/Volt/Volt/src/Volt/Asset/AssetManager.cpp index 541ffbf8d..6da7e55c0 100644 --- a/Volt/Volt/src/Volt/Asset/AssetManager.cpp +++ b/Volt/Volt/src/Volt/Asset/AssetManager.cpp @@ -63,9 +63,9 @@ namespace Volt m_assetImporters.emplace(AssetType::Font, CreateScope()); // Done m_assetImporters.emplace(AssetType::PhysicsMaterial, CreateScope()); // Done m_assetImporters.emplace(AssetType::Video, CreateScope()); // Done - m_assetImporters.emplace(AssetType::BehaviorGraph, CreateScope()); - m_assetImporters.emplace(AssetType::BlendSpace, CreateScope()); - m_assetImporters.emplace(AssetType::PostProcessingStack, CreateScope()); + m_assetImporters.emplace(AssetType::BehaviorGraph, CreateScope()); // Done + m_assetImporters.emplace(AssetType::BlendSpace, CreateScope()); // Done + m_assetImporters.emplace(AssetType::PostProcessingStack, CreateScope()); // Done m_assetImporters.emplace(AssetType::PostProcessingMaterial, CreateScope()); m_assetImporters.emplace(AssetType::NetContract, CreateScope()); diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.cpp new file mode 100644 index 000000000..2b930ee74 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.cpp @@ -0,0 +1,237 @@ +#include "vtpch.h" +#include "BehaviourTreeSerializer.h" + +#include "Volt/Asset/AssetManager.h" +#include "Volt/BehaviorTree/BehaviorTree.hpp" + +namespace Volt +{ + constexpr uint32_t CURRENT_ASSET_VERSION = 1; + + struct SerializedDecorator + { + UUID uuid; + std::string compareFunctionName; + BehaviorTree::eDecoratorType type; + + static void Serialize(BinaryStreamWriter& streamWriter, const SerializedDecorator& data) + { + streamWriter.Write(data.uuid); + streamWriter.Write(data.compareFunctionName); + streamWriter.Write(data.type); + } + + static void Deserialize(BinaryStreamReader& streamReader, SerializedDecorator& outData) + { + streamReader.Read(outData.uuid); + streamReader.Read(outData.compareFunctionName); + streamReader.Read(outData.type); + } + }; + + struct SerializedLeaf + { + UUID uuid; + std::string functionName; + + static void Serialize(BinaryStreamWriter& streamWriter, const SerializedLeaf& data) + { + streamWriter.Write(data.uuid); + streamWriter.Write(data.functionName); + } + + static void Deserialize(BinaryStreamReader& streamReader, SerializedLeaf& outData) + { + streamReader.Read(outData.uuid); + streamReader.Read(outData.functionName); + } + }; + + struct SerializedLink + { + UUID id; + UUID parentId; + UUID childId; + }; + + struct SerializedPosition + { + UUID id; + std::string positionString; + + static void Serialize(BinaryStreamWriter& streamWriter, const SerializedPosition& data) + { + streamWriter.Write(data.id); + streamWriter.Write(data.positionString); + } + + static void Deserialize(BinaryStreamReader& streamReader, SerializedPosition& outData) + { + streamReader.Read(outData.id); + streamReader.Read(outData.positionString); + } + }; + + struct BehaviourTreeSerializationData + { + std::vector sequenceIDs; + std::vector selectorIDs; + std::vector decorators; + std::vector leafs; + std::vector links; + std::vector positions; + + static void Serialize(BinaryStreamWriter& streamWriter, const BehaviourTreeSerializationData& data) + { + streamWriter.Write(data.sequenceIDs); + streamWriter.Write(data.selectorIDs); + streamWriter.Write(data.decorators); + streamWriter.Write(data.leafs); + streamWriter.WriteRaw(data.links); + streamWriter.Write(data.positions); + } + + static void Deserialize(BinaryStreamReader& streamReader, BehaviourTreeSerializationData& outData) + { + streamReader.Read(outData.sequenceIDs); + streamReader.Read(outData.selectorIDs); + streamReader.Read(outData.decorators); + streamReader.Read(outData.leafs); + streamReader.ReadRaw(outData.links); + streamReader.Read(outData.positions); + } + }; + + void BehaviourTreeSerializer::Serialize(const AssetMetadata& metadata, const Ref& asset) const + { + Ref tree = std::reinterpret_pointer_cast(asset); + UUID rootID = tree->GetRoot(); + + BehaviourTreeSerializationData serializationData{}; + + for (const auto& [id, node] : tree->GetNodeManager().m_nodes) + { + switch (node->m_kind) + { + case BehaviorTree::eNodeKind::DECORATOR: + { + auto decorator = std::reinterpret_pointer_cast(tree->GetNodeManager().GetNodeFromUUID(id)); + + auto& serDecorator = serializationData.decorators.emplace_back(); + serDecorator.uuid = id; + serDecorator.compareFunctionName = decorator->m_if; + serDecorator.type = decorator->m_type; + + break; + } + + case BehaviorTree::eNodeKind::LEAF: + { + auto leaf = std::reinterpret_pointer_cast(tree->GetNodeManager().GetNodeFromUUID(id)); + + auto& serLeaf = serializationData.leafs.emplace_back(); + serLeaf.uuid = leaf->GetUUID(); + serLeaf.functionName = leaf->m_monoScriptFunctonName; + + break; + } + + case BehaviorTree::eNodeKind::SELECTOR: serializationData.selectorIDs.push_back(id); break; + case BehaviorTree::eNodeKind::SEQUENCE: serializationData.sequenceIDs.push_back(id); break; + } + } + + for (const auto& [id, links] : tree->GetNodeManager().m_links) + { + for (const auto& link : links) + { + auto& newLink = serializationData.links.emplace_back(); + newLink.id = link.m_uuid; + newLink.parentId = link.m_parentID; + newLink.childId = link.m_childID; + } + } + + for (const auto& [id, node] : tree->GetNodeManager().m_nodes) + { + auto& pos = serializationData.positions.emplace_back(); + pos.id = id; + pos.positionString = node->GetPos(); + } + + BinaryStreamWriter streamWriter{}; + const size_t compressedDataOffset = AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); + + streamWriter.Write(serializationData); + + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + streamWriter.WriteToDisk(filePath, true, compressedDataOffset); + } + + bool BehaviourTreeSerializer::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const + { + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + + if (!std::filesystem::exists(filePath)) + { + VT_CORE_ERROR("File {0} not found!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Missing, true); + return false; + } + + BinaryStreamReader streamReader{ filePath }; + + if (!streamReader.IsStreamValid()) + { + VT_CORE_ERROR("Failed to open file: {0}!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Invalid, true); + return false; + } + + SerializedAssetMetadata serializedMetadata = AssetSerializer::ReadMetadata(streamReader); + + BehaviourTreeSerializationData serializationData{}; + streamReader.Read(serializationData); + + Ref behaviorTree = std::reinterpret_pointer_cast(destinationAsset); + + for (const auto& node : serializationData.sequenceIDs) + { + behaviorTree->CreateNode(node); + } + + for (const auto& node : serializationData.selectorIDs) + { + behaviorTree->CreateNode(node); + } + + for (const auto& node : serializationData.decorators) + { + auto newNodeId = behaviorTree->CreateNode(node.uuid); + auto newNode = std::reinterpret_pointer_cast(behaviorTree->GetNodeManager().GetNodeFromUUID(newNodeId)); + + newNode->m_type = node.type; + newNode->m_if = node.compareFunctionName; + } + + for (const auto& node : serializationData.leafs) + { + auto newNodeId = behaviorTree->CreateNode(node.uuid); + auto newNode = std::reinterpret_pointer_cast(behaviorTree->GetNodeManager().GetNodeFromUUID(newNodeId)); + + newNode->m_monoScriptFunctonName = node.functionName; + } + + for (const auto& link : serializationData.links) + { + behaviorTree->GetNodeManager().RegisterLink(link.parentId, link.childId, link.id); + } + + for (const auto& node : serializationData.positions) + { + behaviorTree->GetNodeManager().GetNodeFromUUID(node.id)->SetPos(node.positionString); + } + + return true; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.h b/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.h new file mode 100644 index 000000000..983a10f8e --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/BehaviourTreeSerializer.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Volt/Asset/ImportersNew/AssetSerializer.h" + +namespace Volt +{ + class BehaviourTreeSerializer : public AssetSerializer + { + public: + void Serialize(const AssetMetadata& metadata, const Ref& asset) const override; + bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; + }; +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.cpp new file mode 100644 index 000000000..8156761bd --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.cpp @@ -0,0 +1,71 @@ +#include "vtpch.h" +#include "BlendSpaceSerializer.h" + +#include "Volt/Asset/AssetManager.h" +#include "Volt/Animation/BlendSpace.h" + +namespace Volt +{ + constexpr uint32_t CURRENT_ASSET_VERSION = 1; + + struct SerializedAnimation + { + AssetHandle handle; + glm::vec2 value; + }; + + struct BlendSpaceSerializationData + { + BlendSpaceDimension dimension; + glm::vec2 horizontalValues; + glm::vec2 verticalValues; + + std::vector animations; + + static void Serialize(BinaryStreamWriter& streamWriter, const BlendSpaceSerializationData& data) + { + streamWriter.Write(data.dimension); + streamWriter.Write(data.horizontalValues); + streamWriter.Write(data.verticalValues); + streamWriter.WriteRaw(data.animations); + } + + static void Deserialize(BinaryStreamReader& streamReader, BlendSpaceSerializationData& outData) + { + streamReader.Read(outData.dimension); + streamReader.Read(outData.horizontalValues); + streamReader.Read(outData.verticalValues); + streamReader.ReadRaw(outData.animations); + } + }; + + void BlendSpaceSerializer::Serialize(const AssetMetadata& metadata, const Ref& asset) const + { + Ref blendSpace = std::reinterpret_pointer_cast(asset); + + BlendSpaceSerializationData serializationData{}; + serializationData.dimension = blendSpace->myDimension; + serializationData.horizontalValues = blendSpace->myHorizontalValues; + serializationData.verticalValues = blendSpace->myVerticalValues; + + for (const auto& anim : blendSpace->myAnimations) + { + auto& serAnim = serializationData.animations.emplace_back(); + serAnim.handle = anim.second; + serAnim.value = anim.first; + } + + BinaryStreamWriter streamWriter{}; + const size_t compressedDataOffset = AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); + + streamWriter.Write(serializationData); + + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + streamWriter.WriteToDisk(filePath, true, compressedDataOffset); + } + + bool BlendSpaceSerializer::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const + { + return false; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.h b/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.h new file mode 100644 index 000000000..112a7a831 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/BlendSpaceSerializer.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Volt/Asset/ImportersNew/AssetSerializer.h" + +namespace Volt +{ + class BlendSpaceSerializer : public AssetSerializer + { + public: + void Serialize(const AssetMetadata& metadata, const Ref& asset) const override; + bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; + }; +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp index 6ea4023ae..5ee257427 100644 --- a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshSerializer.cpp @@ -1,12 +1,11 @@ #include "vtpch.h" #include "MeshSerializer.h" +#include "Volt/Asset/AssetManager.h" #include "Volt/Asset/Mesh/Mesh.h" #include "Volt/Asset/Mesh/Material.h" #include "Volt/Asset/Serialization/AssetSerializationCommon.h" -#include "Volt/Asset/AssetManager.h" - namespace Volt { constexpr uint32_t CURRENT_ASSET_VERSION = 1; diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.cpp new file mode 100644 index 000000000..b051e7feb --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.cpp @@ -0,0 +1,79 @@ +#include "vtpch.h" +#include "PostProcessingStackSerializer.h" + +#include "Volt/Asset/AssetManager.h" +#include "Volt/Asset/Rendering/PostProcessingStack.h" + +namespace Volt +{ + constexpr uint32_t CURRENT_ASSET_VERSION = 1; + + struct PostProcessingStackSerializationData + { + std::vector effects; + + static void Serialize(BinaryStreamWriter& streamWriter, const PostProcessingStackSerializationData& data) + { + streamWriter.WriteRaw(data.effects); + } + + static void Deserialize(BinaryStreamReader& streamReader, PostProcessingStackSerializationData& outData) + { + streamReader.ReadRaw(outData.effects); + } + }; + + void PostProcessingStackSerializer::Serialize(const AssetMetadata& metadata, const Ref& asset) const + { + Ref postStack = std::reinterpret_pointer_cast(asset); + + PostProcessingStackSerializationData serializationData{}; + for (const auto& effect : postStack->myPostProcessingStack) + { + serializationData.effects.push_back(effect.materialHandle); + } + + BinaryStreamWriter streamWriter{}; + const size_t compressedDataOffset = AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); + + streamWriter.Write(serializationData); + + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + streamWriter.WriteToDisk(filePath, true, compressedDataOffset); + } + + bool PostProcessingStackSerializer::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const + { + const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); + + if (!std::filesystem::exists(filePath)) + { + VT_CORE_ERROR("File {0} not found!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Missing, true); + return false; + } + + BinaryStreamReader streamReader{ filePath }; + + if (!streamReader.IsStreamValid()) + { + VT_CORE_ERROR("Failed to open file: {0}!", metadata.filePath); + destinationAsset->SetFlag(AssetFlag::Invalid, true); + return false; + } + + SerializedAssetMetadata serializedMetadata = AssetSerializer::ReadMetadata(streamReader); + + Ref postStack = std::reinterpret_pointer_cast(destinationAsset); + + PostProcessingStackSerializationData serializationData{}; + streamReader.Read(serializationData); + + for (const auto& effectNode : serializationData.effects) + { + postStack->myPostProcessingStack.emplace_back(effectNode); + } + + return true; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.h b/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.h new file mode 100644 index 000000000..67c1d28cd --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/PostProcessingStackSerializer.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Volt/Asset/ImportersNew/AssetSerializer.h" + +namespace Volt +{ + class PostProcessingStackSerializer : public AssetSerializer + { + public: + void Serialize(const AssetMetadata& metadata, const Ref& asset) const override; + bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; + }; +} diff --git a/Volt/Volt/src/Volt/Asset/Rendering/PostProcessingStack.h b/Volt/Volt/src/Volt/Asset/Rendering/PostProcessingStack.h index da216deb7..65e0a5a40 100644 --- a/Volt/Volt/src/Volt/Asset/Rendering/PostProcessingStack.h +++ b/Volt/Volt/src/Volt/Asset/Rendering/PostProcessingStack.h @@ -31,6 +31,7 @@ namespace Volt private: friend class PostProcessingStackImporter; + friend class PostProcessingStackSerializer; std::vector myPostProcessingStack; }; diff --git a/Volt/Volt/src/Volt/BehaviorTree/NodeManager.cpp b/Volt/Volt/src/Volt/BehaviorTree/NodeManager.cpp index 3ea9c43b3..3e06b449c 100644 --- a/Volt/Volt/src/Volt/BehaviorTree/NodeManager.cpp +++ b/Volt/Volt/src/Volt/BehaviorTree/NodeManager.cpp @@ -3,11 +3,11 @@ namespace Volt::BehaviorTree { - Ref NodeManager::GetNodeFromUUID(const UUID& in_uuid) + Ref NodeManager::GetNodeFromUUID(const UUID& in_uuid) const { if (m_nodes.find(in_uuid) == m_nodes.end()) return nullptr; - return m_nodes[in_uuid]; + return m_nodes.at(in_uuid); } const std::vector& NodeManager::GetLinksFromUUID(const UUID& in_uuid) diff --git a/Volt/Volt/src/Volt/BehaviorTree/NodeManager.h b/Volt/Volt/src/Volt/BehaviorTree/NodeManager.h index 5ca0cec57..d3d607616 100644 --- a/Volt/Volt/src/Volt/BehaviorTree/NodeManager.h +++ b/Volt/Volt/src/Volt/BehaviorTree/NodeManager.h @@ -13,7 +13,7 @@ namespace Volt::BehaviorTree class NodeManager { public: - Ref GetNodeFromUUID(const UUID& in_uuid); + Ref GetNodeFromUUID(const UUID& in_uuid) const; const std::vector& GetLinksFromUUID(const UUID& in_uuid); const Link& GetLink(const UUID& in_uuid); @@ -33,6 +33,7 @@ namespace Volt::BehaviorTree private: friend class Tree; friend class BehaviorTreeImporter; + friend class BehaviourTreeSerializer; friend class Node; NodeManager(); ~NodeManager();