From 2baa32b79999bd1aa7580f79b1907524a845233b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20J=C3=B6nsson?= Date: Thu, 29 Feb 2024 22:46:16 +0100 Subject: [PATCH] Started concepting new asset serialization --- .../src/Sandbox/Utility/EditorResources.cpp | 6 +- .../src/Sandbox/Utility/EditorUtilities.cpp | 20 +- .../src/Volt/Asset/Importers/FbxImporter.cpp | 91 ++++---- .../src/Volt/Asset/Importers/FbxImporter.h | 8 +- .../src/Volt/Asset/Importers/GLTFImporter.cpp | 42 ++-- .../src/Volt/Asset/Importers/GLTFImporter.h | 8 +- .../Asset/Importers/MeshSourceImporter.cpp | 6 +- .../Volt/Asset/Importers/MeshTypeImporter.cpp | 12 +- .../Volt/Asset/Importers/MeshTypeImporter.h | 12 +- .../src/Volt/Asset/Importers/ObjImporter.h | 6 +- .../Volt/Asset/Importers/VTMeshImporter.cpp | 36 ++- .../src/Volt/Asset/Importers/VTMeshImporter.h | 6 +- .../Asset/ImportersNew/AssetSerializer.cpp | 18 ++ .../Volt/Asset/ImportersNew/AssetSerializer.h | 21 ++ .../Volt/Asset/ImportersNew/MeshImporter.cpp | 60 +++++ .../Volt/Asset/ImportersNew/MeshImporter.h | 15 ++ .../Asset/ImportersNew/SourceMeshImporter.cpp | 29 +++ .../Asset/ImportersNew/SourceMeshImporter.h | 13 ++ Volt/Volt/src/Volt/Asset/Mesh/Mesh.h | 1 + .../AssetSerializationCommon.cpp | 14 ++ .../Serialization/AssetSerializationCommon.h | 22 ++ Volt/Volt/src/Volt/Core/UUID.cpp | 7 + Volt/Volt/src/Volt/Core/UUID.h | 4 + .../src/Volt/Rendering/BoundingStructures.h | 1 - .../Utility/FileIO/BinaryStreamWriter.cpp | 28 +++ .../Volt/Utility/FileIO/BinaryStreamWriter.h | 211 ++++++++++++++++++ .../Volt/Utility/FileIO/YAMLStreamWriter.h | 2 - 27 files changed, 566 insertions(+), 133 deletions(-) create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.cpp create mode 100644 Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.h create mode 100644 Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp create mode 100644 Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h create mode 100644 Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp create mode 100644 Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorResources.cpp b/Volt/Sandbox/src/Sandbox/Utility/EditorResources.cpp index 8ee949f60..b2995e7cb 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorResources.cpp +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorResources.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include #include #include @@ -152,8 +154,8 @@ Ref EditorResources::TryLoadIcon(const std::filesystem::path& p Ref EditorResources::TryLoadMesh(const std::filesystem::path& path) { - Ref mesh = Volt::MeshTypeImporter::ImportMesh(path); - if (!mesh) + Ref mesh = CreateRef(); + if (!Volt::MeshTypeImporter::ImportMesh(path, *mesh)) { mesh = Volt::Shape::CreateUnitCube(); } diff --git a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp index ea55bfd98..e266fe713 100644 --- a/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp +++ b/Volt/Sandbox/src/Sandbox/Utility/EditorUtilities.cpp @@ -234,8 +234,8 @@ bool EditorUtils::ReimportSourceMesh(Volt::AssetHandle assetHandle, Ref newAnim = Volt::MeshTypeImporter::ImportAnimation(Volt::ProjectManager::GetDirectory() / sourcePath, targetSkeleton); - if (!newAnim) + Ref newAnim = CreateRef(); + if (!Volt::MeshTypeImporter::ImportAnimation(Volt::ProjectManager::GetDirectory() / sourcePath, targetSkeleton, *newAnim)) { UI::Notify(NotificationType::Error, "Unable to re import animation!", std::format("Failed to import animation from {0}!", sourcePath.string())); break; @@ -253,8 +253,8 @@ bool EditorUtils::ReimportSourceMesh(Volt::AssetHandle assetHandle, Ref newSkel = Volt::MeshTypeImporter::ImportSkeleton(Volt::ProjectManager::GetDirectory() / sourcePath); - if (!newSkel) + Ref newSkel = CreateRef(); + if (!Volt::MeshTypeImporter::ImportSkeleton(Volt::ProjectManager::GetDirectory() / sourcePath, *newSkel)) { UI::Notify(NotificationType::Error, "Unable to re import skeleton!", std::format("Failed to import skeleton from {0}!", sourcePath.string())); break; @@ -274,8 +274,8 @@ bool EditorUtils::ReimportSourceMesh(Volt::AssetHandle assetHandle, Ref originalMesh = std::reinterpret_pointer_cast(originalAsset); - Ref newMesh = Volt::MeshTypeImporter::ImportMesh(Volt::ProjectManager::GetDirectory() / sourcePath); - if (!newMesh || !newMesh->IsValid()) + Ref newMesh = CreateRef(); + if (!Volt::MeshTypeImporter::ImportMesh(Volt::ProjectManager::GetDirectory() / sourcePath, *newMesh)) { UI::Notify(NotificationType::Error, "Unable to re import mesh!", std::format("Failed to import mesh from {0}!", sourcePath.string())); break; @@ -503,8 +503,8 @@ ImportState EditorUtils::MeshImportModal(const std::string& aId, MeshImportData& if (aImportData.importSkeleton) { - Ref skeleton = Volt::MeshTypeImporter::ImportSkeleton(Volt::ProjectManager::GetDirectory() / aMeshToImport); - if (!skeleton) + Ref skeleton = CreateRef(); + if (!Volt::MeshTypeImporter::ImportSkeleton(Volt::ProjectManager::GetDirectory() / aMeshToImport, *skeleton)) { UI::Notify(NotificationType::Error, "Failed to import skeleton!", std::format("Failed to import skeleton from {}!", aMeshToImport.string())); } @@ -527,8 +527,8 @@ ImportState EditorUtils::MeshImportModal(const std::string& aId, MeshImportData& } else { - Ref animation = Volt::MeshTypeImporter::ImportAnimation(Volt::ProjectManager::GetDirectory() / aMeshToImport, targetSkeleton); - if (!animation) + Ref animation = CreateRef(); + if (!Volt::MeshTypeImporter::ImportAnimation(Volt::ProjectManager::GetDirectory() / aMeshToImport, targetSkeleton, *animation)) { UI::Notify(NotificationType::Error, "Failed to import animation!", std::format("Failed to import animaition from {}!", aMeshToImport.string())); } diff --git a/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.cpp index a13a40a50..5d3ef801d 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.cpp @@ -18,7 +18,7 @@ namespace Volt { - Ref FbxImporter::ImportMeshImpl(const std::filesystem::path& path) + bool FbxImporter::ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) { TGA::FBX::Importer::InitImporter(); @@ -27,29 +27,28 @@ namespace Volt { if (!TGA::FBX::Importer::LoadMeshW(path.wstring(), tgaMesh)) { - return nullptr; + return false; } } catch (const std::exception& e) { VT_CORE_ERROR("[FBXImporter] Unable to import animation! Reason: {0}", e.what()); - return nullptr; + return false; } if (!tgaMesh.IsValid()) { - return nullptr; + return false; } - Ref mesh = CreateRef(); - mesh->myMaterial = CreateRef(); - mesh->myMaterial->myName = path.stem().string() + "_mat"; + dstMesh.myMaterial = CreateRef(); + dstMesh.myMaterial->myName = path.stem().string() + "_mat"; for (const auto& element : tgaMesh.Elements) { - auto& newSubMesh = mesh->mySubMeshes.emplace_back(); - newSubMesh.vertexStartOffset = static_cast(mesh->myVertices.size()); - newSubMesh.indexStartOffset = static_cast(mesh->myIndices.size()); + auto& newSubMesh = dstMesh.mySubMeshes.emplace_back(); + newSubMesh.vertexStartOffset = static_cast(dstMesh.myVertices.size()); + newSubMesh.indexStartOffset = static_cast(dstMesh.myIndices.size()); newSubMesh.vertexCount = static_cast(element.Vertices.size()); newSubMesh.indexCount = static_cast(element.Indices.size()); newSubMesh.materialIndex = element.MaterialIndex; @@ -66,7 +65,7 @@ namespace Volt for (const auto& tgaVertex : element.Vertices) { - auto& newVertex = mesh->myVertices.emplace_back(); + auto& newVertex = dstMesh.myVertices.emplace_back(); newVertex.position = *reinterpret_cast(tgaVertex.Position); newVertex.normal = *reinterpret_cast(tgaVertex.Normal); newVertex.tangent = *reinterpret_cast(tgaVertex.Tangent); @@ -75,32 +74,32 @@ namespace Volt newVertex.weights = *reinterpret_cast(tgaVertex.BoneWeights); } - mesh->myIndices.insert(mesh->myIndices.end(), element.Indices.begin(), element.Indices.end()); + dstMesh.myIndices.insert(dstMesh.myIndices.end(), element.Indices.begin(), element.Indices.end()); } if (tgaMesh.Materials.empty()) { - mesh->myMaterial->CreateSubMaterial(ShaderRegistry::GetShader("Illum")); + dstMesh.myMaterial->CreateSubMaterial(ShaderRegistry::GetShader("Illum")); } else { for (const auto& material : tgaMesh.Materials) { - mesh->myMaterial->CreateSubMaterial(ShaderRegistry::GetShader("Illum"), material.MaterialName); + dstMesh.myMaterial->CreateSubMaterial(ShaderRegistry::GetShader("Illum"), material.MaterialName); } } - mesh->myBoundingBox = BoundingBox{ *reinterpret_cast(tgaMesh.BoxBounds.Max), *reinterpret_cast(tgaMesh.BoxBounds.Min) }; - mesh->myBoundingSphere.center = { tgaMesh.BoxSphereBounds.Center[0], tgaMesh.BoxSphereBounds.Center[1], tgaMesh.BoxSphereBounds.Center[2] }; - mesh->myBoundingSphere.radius = tgaMesh.BoxSphereBounds.Radius; + dstMesh.myBoundingBox = BoundingBox{ *reinterpret_cast(tgaMesh.BoxBounds.Max), *reinterpret_cast(tgaMesh.BoxBounds.Min) }; + dstMesh.myBoundingSphere.center = { tgaMesh.BoxSphereBounds.Center[0], tgaMesh.BoxSphereBounds.Center[1], tgaMesh.BoxSphereBounds.Center[2] }; + dstMesh.myBoundingSphere.radius = tgaMesh.BoxSphereBounds.Radius; TGA::FBX::Importer::UninitImporter(); - mesh->Construct(); - return mesh; + dstMesh.Construct(); + return true; } - Ref FbxImporter::ImportSkeletonImpl(const std::filesystem::path& path) + bool FbxImporter::ImportSkeletonImpl(const std::filesystem::path& path, Skeleton& dstSkeleton) { TGA::FBX::Importer::InitImporter(); @@ -110,27 +109,26 @@ namespace Volt { if (!TGA::FBX::Importer::LoadMeshW(path.wstring(), tgaMesh)) { - return nullptr; + return false; } } catch (const std::exception& e) { VT_CORE_ERROR("[FBXImporter] Unable to import animation! Reason: {0}", e.what()); - return nullptr; + return false; } - Ref skeleton = CreateRef(); - skeleton->myJoints.resize(tgaMesh.Skeleton.Bones.size()); - skeleton->myInverseBindPose.resize(tgaMesh.Skeleton.Bones.size()); - skeleton->myRestPose.resize(tgaMesh.Skeleton.Bones.size()); + dstSkeleton.myJoints.resize(tgaMesh.Skeleton.Bones.size()); + dstSkeleton.myInverseBindPose.resize(tgaMesh.Skeleton.Bones.size()); + dstSkeleton.myRestPose.resize(tgaMesh.Skeleton.Bones.size()); - ProcessSkeleton(skeleton, tgaMesh.Skeleton.Bones, 0); + ProcessSkeleton(dstSkeleton, tgaMesh.Skeleton.Bones, 0); TGA::FBX::Importer::UninitImporter(); - return skeleton; + return true; } - Ref FbxImporter::ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton) + bool FbxImporter::ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton, Animation& dstAnimation) { TGA::FBX::Importer::InitImporter(); @@ -140,22 +138,21 @@ namespace Volt { if (!TGA::FBX::Importer::LoadAnimationW(path.wstring(), tgaAnimation)) { - return nullptr; + return false; } } catch (const std::exception& e) { VT_CORE_ERROR("[FBXImporter] Unable to import animation! Reason: {0}", e.what()); - return nullptr; + return false; } - Ref animation = CreateRef(); - animation->myFramesPerSecond = static_cast(tgaAnimation.FramesPerSecond); - animation->myDuration = static_cast(tgaAnimation.Duration); + dstAnimation.myFramesPerSecond = static_cast(tgaAnimation.FramesPerSecond); + dstAnimation.myDuration = static_cast(tgaAnimation.Duration); for (const auto& tgaFrame : tgaAnimation.Frames) { - auto& newFrame = animation->myFrames.emplace_back(); + auto& newFrame = dstAnimation.myFrames.emplace_back(); newFrame.localTRS.resize(targetSkeleton->myJoints.size()); for (const auto& [jointName, localTQS] : tgaFrame.LocalTQS) @@ -176,7 +173,7 @@ namespace Volt } TGA::FBX::Importer::UninitImporter(); - return animation; + return true; } void FbxImporter::ExportMeshImpl(std::vector>, const std::filesystem::path&) @@ -268,23 +265,23 @@ namespace Volt //exporter->Destroy(); } - void FbxImporter::ProcessSkeleton(Ref skeleton, const std::vector& bones, uint32_t currentIndex) + void FbxImporter::ProcessSkeleton(Skeleton& skeleton, const std::vector& bones, uint32_t currentIndex) { const auto& currentJoint = bones.at(currentIndex); - skeleton->myJoints[currentIndex].name = currentJoint.Name; - skeleton->myJoints[currentIndex].parentIndex = currentJoint.ParentIdx; - skeleton->myInverseBindPose[currentIndex] = glm::transpose(*reinterpret_cast(currentJoint.BindPoseInverse.Data)); - skeleton->myJointNameToIndex[currentJoint.Name] = static_cast(currentIndex); + skeleton.myJoints[currentIndex].name = currentJoint.Name; + skeleton.myJoints[currentIndex].parentIndex = currentJoint.ParentIdx; + skeleton.myInverseBindPose[currentIndex] = glm::transpose(*reinterpret_cast(currentJoint.BindPoseInverse.Data)); + skeleton.myJointNameToIndex[currentJoint.Name] = static_cast(currentIndex); - skeleton->myRestPose[currentIndex].position = { currentJoint.restPosition[0], currentJoint.restPosition[1], currentJoint.restPosition[2] }; + skeleton.myRestPose[currentIndex].position = { currentJoint.restPosition[0], currentJoint.restPosition[1], currentJoint.restPosition[2] }; - skeleton->myRestPose[currentIndex].rotation.x = currentJoint.restRotation[0]; - skeleton->myRestPose[currentIndex].rotation.y = currentJoint.restRotation[1]; - skeleton->myRestPose[currentIndex].rotation.z = currentJoint.restRotation[2]; - skeleton->myRestPose[currentIndex].rotation.w = currentJoint.restRotation[3]; + skeleton.myRestPose[currentIndex].rotation.x = currentJoint.restRotation[0]; + skeleton.myRestPose[currentIndex].rotation.y = currentJoint.restRotation[1]; + skeleton.myRestPose[currentIndex].rotation.z = currentJoint.restRotation[2]; + skeleton.myRestPose[currentIndex].rotation.w = currentJoint.restRotation[3]; - skeleton->myRestPose[currentIndex].scale = { currentJoint.restScale[0], currentJoint.restScale[1], currentJoint.restScale[2] }; + skeleton.myRestPose[currentIndex].scale = { currentJoint.restScale[0], currentJoint.restScale[1], currentJoint.restScale[2] }; for (const auto& child : currentJoint.Children) { diff --git a/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.h b/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.h index b6200b09e..2385383a1 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/FbxImporter.h @@ -15,9 +15,9 @@ namespace Volt FbxImporter() = default; protected: - Ref ImportMeshImpl(const std::filesystem::path& path) override; - Ref ImportSkeletonImpl(const std::filesystem::path& path) override; - Ref ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton) override; + bool ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) override; + bool ImportSkeletonImpl(const std::filesystem::path& path, Skeleton& dstSkeleton) override; + bool ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton, Animation& dstAnimation) override; void ExportMeshImpl(std::vector> assets, const std::filesystem::path& path) override; void ExportSkeletonImpl(std::vector> assets, const std::filesystem::path&) override {}; @@ -30,6 +30,6 @@ namespace Volt size_t hash; }; - void ProcessSkeleton(Ref skeleton, const std::vector& bones, uint32_t currentIndex); + void ProcessSkeleton(Skeleton& skeleton, const std::vector& bones, uint32_t currentIndex); }; } diff --git a/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.cpp index e0a602be1..0b662129b 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.cpp @@ -17,12 +17,12 @@ namespace Volt { - Ref GLTFImporter::ImportMeshImpl(const std::filesystem::path& path) + bool GLTFImporter::ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) { if (!std::filesystem::exists(path)) { VT_CORE_ERROR("File does not exist: {0}", path.string().c_str()); - return nullptr; + return false; } tinygltf::Model gltfInput; @@ -43,17 +43,16 @@ namespace Volt if (!loaded) { VT_CORE_ERROR("Unable to load GLTF file {0}! Error: {1}, warning {2}", path.string().c_str(), error.c_str(), warning.c_str()); - return nullptr; + return false; } - Ref mesh = CreateRef(); - mesh->myMaterial = CreateRef(); - mesh->myMaterial->myName = path.stem().string() + "_mat"; + dstMesh.myMaterial = CreateRef(); + dstMesh.myMaterial->myName = path.stem().string() + "_mat"; uint32_t index = 0; for (const auto& mat : gltfInput.materials) { - mesh->myMaterial->mySubMaterials[index] = SubMaterial::Create(mat.name, index, ShaderRegistry::GetShader("Illum")); + dstMesh.myMaterial->mySubMaterials[index] = SubMaterial::Create(mat.name, index, ShaderRegistry::GetShader("Illum")); index++; } @@ -61,15 +60,14 @@ namespace Volt for (int i : scene.nodes) { const tinygltf::Node& node = gltfInput.nodes[i]; - LoadNode(node, gltfInput, nullptr, mesh); + LoadNode(node, gltfInput, nullptr, dstMesh); } - mesh->Construct(); - - return mesh; + dstMesh.Construct(); + return true; } - void GLTFImporter::LoadNode(const tinygltf::Node& inputNode, const tinygltf::Model& inputModel, GLTF::Node*, Ref outMesh) + void GLTFImporter::LoadNode(const tinygltf::Node& inputNode, const tinygltf::Model& inputModel, GLTF::Node*, Mesh& outMesh) { GLTF::Node node{}; @@ -104,8 +102,8 @@ namespace Volt for (const tinygltf::Primitive& gltfPrimitive : mesh.primitives) { - uint32_t firstIndex = (uint32_t)outMesh->myIndices.size(); - uint32_t firstVertex = (uint32_t)outMesh->myVertices.size(); + uint32_t firstIndex = (uint32_t)outMesh.myIndices.size(); + uint32_t firstVertex = (uint32_t)outMesh.myVertices.size(); uint32_t indexCount = 0; size_t vertexCount = 0; @@ -163,7 +161,7 @@ namespace Volt vert.tangent = glm::vec3(tangent.x, tangent.y, tangent.z); - outMesh->myVertices.emplace_back(vert); + outMesh.myVertices.emplace_back(vert); } } @@ -182,7 +180,7 @@ namespace Volt const uint32_t* buf = reinterpret_cast(&buffer.data[accessor.byteOffset + view.byteOffset]); for (size_t index = 0; index < accessor.count; index++) { - outMesh->myIndices.emplace_back(buf[index]); + outMesh.myIndices.emplace_back(buf[index]); } break; @@ -193,7 +191,7 @@ namespace Volt const int16_t* buf = reinterpret_cast(&buffer.data[accessor.byteOffset + view.byteOffset]); for (size_t index = 0; index < accessor.count; index++) { - outMesh->myIndices.emplace_back(buf[index]); + outMesh.myIndices.emplace_back(buf[index]); } break; } @@ -203,7 +201,7 @@ namespace Volt const uint16_t* buf = reinterpret_cast(&buffer.data[accessor.byteOffset + view.byteOffset]); for (size_t index = 0; index < accessor.count; index++) { - outMesh->myIndices.emplace_back(buf[index]); + outMesh.myIndices.emplace_back(buf[index]); } break; } @@ -213,7 +211,7 @@ namespace Volt const uint8_t* buf = reinterpret_cast(&buffer.data[accessor.byteOffset + view.byteOffset]); for (size_t index = 0; index < accessor.count; index++) { - outMesh->myIndices.emplace_back(buf[index]); + outMesh.myIndices.emplace_back(buf[index]); } break; } @@ -224,7 +222,7 @@ namespace Volt } } - auto& subMesh = outMesh->mySubMeshes.emplace_back(); + auto& subMesh = outMesh.mySubMeshes.emplace_back(); subMesh.indexCount = indexCount; subMesh.vertexCount = (uint32_t)vertexCount; subMesh.indexStartOffset = firstIndex; @@ -233,9 +231,9 @@ namespace Volt subMesh.transform = node.transform; subMesh.GenerateHash(); - if (!outMesh->myMaterial->mySubMaterials.contains(subMesh.materialIndex)) + if (!outMesh.myMaterial->mySubMaterials.contains(subMesh.materialIndex)) { - outMesh->myMaterial->mySubMaterials[subMesh.materialIndex] = SubMaterial::Create(inputModel.materials[subMesh.materialIndex].name, subMesh.materialIndex, ShaderRegistry::GetShader("Deferred")); + outMesh.myMaterial->mySubMaterials[subMesh.materialIndex] = SubMaterial::Create(inputModel.materials[subMesh.materialIndex].name, subMesh.materialIndex, ShaderRegistry::GetShader("Deferred")); } } } diff --git a/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.h b/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.h index 89d4acf12..7db764ec0 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/GLTFImporter.h @@ -44,11 +44,11 @@ namespace Volt GLTFImporter() = default; protected: - Ref ImportMeshImpl(const std::filesystem::path& path) override; - Ref ImportSkeletonImpl(const std::filesystem::path&) override { return nullptr; } - Ref ImportAnimationImpl(const std::filesystem::path&, Ref) override { return nullptr; } + bool ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) override; + bool ImportSkeletonImpl(const std::filesystem::path&, Skeleton& dstSkeleton) override { return false; } + bool ImportAnimationImpl(const std::filesystem::path&, Ref, Animation& dstAnimation) override { return false; } private: - void LoadNode(const tinygltf::Node& inputNode, const tinygltf::Model& inputModel, GLTF::Node* parent, Ref outMesh); + void LoadNode(const tinygltf::Node& inputNode, const tinygltf::Model& inputModel, GLTF::Node* parent, Mesh& outMesh); }; } diff --git a/Volt/Volt/src/Volt/Asset/Importers/MeshSourceImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/MeshSourceImporter.cpp index 2643484d3..6d700c12f 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/MeshSourceImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/MeshSourceImporter.cpp @@ -11,7 +11,6 @@ namespace Volt { bool MeshSourceImporter::Load(const AssetMetadata& metadata, Ref& asset) const { - asset = CreateRef(); const auto filePath = AssetManager::GetFilesystemPath(metadata.filePath); if (!std::filesystem::exists(filePath)) @@ -20,15 +19,14 @@ namespace Volt asset->SetFlag(AssetFlag::Missing, true); return false; } - auto mesh = MeshTypeImporter::ImportMesh(filePath); - if (!mesh) + Ref destinationMesh = std::reinterpret_pointer_cast(asset); + if (!MeshTypeImporter::ImportMesh(filePath, *destinationMesh)) { asset->SetFlag(AssetFlag::Invalid, true); return false; } - asset = mesh; return true; } diff --git a/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.cpp index 8bfccb180..f8f6e73f9 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.cpp @@ -21,19 +21,19 @@ namespace Volt myImporters.clear(); } - Ref MeshTypeImporter::ImportMesh(const std::filesystem::path& path) + bool MeshTypeImporter::ImportMesh(const std::filesystem::path& path, Mesh& dstMesh) { - return myImporters[FormatFromExtension(path)]->ImportMeshImpl(path); + return myImporters[FormatFromExtension(path)]->ImportMeshImpl(path, dstMesh); } - Ref MeshTypeImporter::ImportSkeleton(const std::filesystem::path& path) + bool MeshTypeImporter::ImportSkeleton(const std::filesystem::path& path, Skeleton& dstSkeleton) { - return myImporters[FormatFromExtension(path)]->ImportSkeletonImpl(path); + return myImporters[FormatFromExtension(path)]->ImportSkeletonImpl(path, dstSkeleton); } - Ref MeshTypeImporter::ImportAnimation(const std::filesystem::path& path, Ref targetSkeleton) + bool MeshTypeImporter::ImportAnimation(const std::filesystem::path& path, Ref targetSkeleton, Animation& dstAnimation) { - return myImporters[FormatFromExtension(path)]->ImportAnimationImpl(path, targetSkeleton); + return myImporters[FormatFromExtension(path)]->ImportAnimationImpl(path, targetSkeleton, dstAnimation); } void MeshTypeImporter::ExportMesh(std::vector> assets, const std::filesystem::path& path) diff --git a/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.h b/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.h index d22c2b707..da02cec9f 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/MeshTypeImporter.h @@ -18,18 +18,18 @@ namespace Volt static void Initialize(); static void Shutdown(); - static Ref ImportMesh(const std::filesystem::path& path); - static Ref ImportSkeleton(const std::filesystem::path& path); - static Ref ImportAnimation(const std::filesystem::path& path, Ref targetSkeleton); + static bool ImportMesh(const std::filesystem::path& path, Mesh& dstMesh); + static bool ImportSkeleton(const std::filesystem::path& path, Skeleton& dstSkeleton); + static bool ImportAnimation(const std::filesystem::path& path, Ref targetSkeleton, Animation& dstAnimation); static void ExportMesh(std::vector> assets, const std::filesystem::path& path); static void ExportSkeleton(std::vector> assets, const std::filesystem::path& path); static void ExportAnimation(std::vector> assets, const std::filesystem::path& path); protected: - virtual Ref ImportMeshImpl(const std::filesystem::path& path) = 0; - virtual Ref ImportSkeletonImpl(const std::filesystem::path& path) = 0; - virtual Ref ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton) = 0; + virtual bool ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) = 0; + virtual bool ImportSkeletonImpl(const std::filesystem::path& path, Skeleton& dstSkeleton) = 0; + virtual bool ImportAnimationImpl(const std::filesystem::path& path, Ref targetSkeleton, Animation& dstAnimation) = 0; virtual void ExportMeshImpl(std::vector>, const std::filesystem::path&) {}; virtual void ExportSkeletonImpl(std::vector>, const std::filesystem::path&) {}; diff --git a/Volt/Volt/src/Volt/Asset/Importers/ObjImporter.h b/Volt/Volt/src/Volt/Asset/Importers/ObjImporter.h index 5fa2556a7..6006613f9 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/ObjImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/ObjImporter.h @@ -10,9 +10,9 @@ namespace Volt ObjImporter() = default; protected: - Ref ImportMeshImpl(const std::filesystem::path&) override { return nullptr; }; - Ref ImportSkeletonImpl(const std::filesystem::path&) override { return nullptr; } - Ref ImportAnimationImpl(const std::filesystem::path&, Ref) override { return nullptr; } + bool ImportMeshImpl(const std::filesystem::path&, Mesh& mesh) override { return false; }; + bool ImportSkeletonImpl(const std::filesystem::path&, Skeleton& skeleton) override { return false; } + bool ImportAnimationImpl(const std::filesystem::path&, Ref, Animation& animation) override { return false; } void ExportMeshImpl(std::vector> assets, const std::filesystem::path& path) override; void ExportSkeletonImpl(std::vector>, const std::filesystem::path&) override {}; diff --git a/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.cpp b/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.cpp index a73884c59..0f33e83c2 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.cpp +++ b/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.cpp @@ -12,12 +12,12 @@ namespace Volt { - Ref VTMeshImporter::ImportMeshImpl(const std::filesystem::path& path) + bool VTMeshImporter::ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) { if (!std::filesystem::exists(path)) { VT_CORE_ERROR("File does not exist: {0}", path.string().c_str()); - return nullptr; + return false; } std::ifstream file(path, std::ios::in | std::ios::binary); @@ -33,42 +33,40 @@ namespace Volt file.read(reinterpret_cast(totalData.data()), totalData.size()); file.close(); - Ref mesh = CreateRef(); - size_t offset = 0; const uint32_t subMeshCount = *(uint32_t*)&totalData[offset]; offset += sizeof(uint32_t); const AssetHandle materialHandle = *(AssetHandle*)&totalData[offset]; - mesh->myMaterial = AssetManager::GetAsset(materialHandle); + dstMesh.myMaterial = AssetManager::GetAsset(materialHandle); offset += sizeof(AssetHandle); const uint32_t vertexCount = *(uint32_t*)&totalData[offset]; offset += sizeof(uint32_t); - mesh->myVertices.resize(vertexCount); - memcpy_s(mesh->myVertices.data(), sizeof(Vertex) * vertexCount, &totalData[offset], sizeof(Vertex) * vertexCount); + dstMesh.myVertices.resize(vertexCount); + memcpy_s(dstMesh.myVertices.data(), sizeof(Vertex) * vertexCount, &totalData[offset], sizeof(Vertex) * vertexCount); offset += sizeof(Vertex) * vertexCount; const uint32_t indexCount = *(uint32_t*)&totalData[offset]; offset += sizeof(uint32_t); - mesh->myIndices.resize(indexCount); - memcpy_s(mesh->myIndices.data(), sizeof(uint32_t) * indexCount, &totalData[offset], sizeof(uint32_t) * indexCount); + dstMesh.myIndices.resize(indexCount); + memcpy_s(dstMesh.myIndices.data(), sizeof(uint32_t) * indexCount, &totalData[offset], sizeof(uint32_t) * indexCount); offset += sizeof(uint32_t) * indexCount; if (!IsValid(subMeshCount, vertexCount, indexCount, srcSize) && path.extension() != ".vtnavmesh") { VT_CORE_ERROR("Mesh {0} is invalid! It needs to be recompiled!", path.string()); - mesh->SetFlag(AssetFlag::Invalid, true); - return mesh; + dstMesh.SetFlag(AssetFlag::Invalid, true); + return false; } - mesh->myBoundingSphere.center = *(glm::vec3*)&totalData[offset]; + dstMesh.myBoundingSphere.center = *(glm::vec3*)&totalData[offset]; offset += sizeof(glm::vec3); - mesh->myBoundingSphere.radius = *(float*)&totalData[offset]; + dstMesh.myBoundingSphere.radius = *(float*)&totalData[offset]; offset += sizeof(float); const uint32_t nameCount = *(uint32_t*)&totalData[offset]; @@ -90,7 +88,7 @@ namespace Volt for (uint32_t i = 0; i < subMeshCount; i++) { - auto& subMesh = mesh->mySubMeshes.emplace_back(); + auto& subMesh = dstMesh.mySubMeshes.emplace_back(); subMesh.materialIndex = *(uint32_t*)&totalData[offset]; offset += sizeof(uint32_t); @@ -118,15 +116,15 @@ namespace Volt subMesh.GenerateHash(); } - if (!mesh->myMaterial) + if (!dstMesh.myMaterial) { - mesh->myMaterial = CreateRef(); - mesh->myMaterial->mySubMaterials.emplace(0, SubMaterial::Create("Null", 0, Renderer::GetDefaultData().defaultShader)); + dstMesh.myMaterial = CreateRef(); + dstMesh.myMaterial->mySubMaterials.emplace(0, SubMaterial::Create("Null", 0, Renderer::GetDefaultData().defaultShader)); } - mesh->Construct(); + dstMesh.Construct(); - return mesh; + return true; } bool VTMeshImporter::IsValid(uint32_t subMeshCount, uint32_t vertexCount, uint32_t indexCount, size_t srcSize) const diff --git a/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.h b/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.h index 44b11754c..3649e2c9d 100644 --- a/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.h +++ b/Volt/Volt/src/Volt/Asset/Importers/VTMeshImporter.h @@ -10,9 +10,9 @@ namespace Volt VTMeshImporter() = default; protected: - Ref ImportMeshImpl(const std::filesystem::path& path) override; - Ref ImportSkeletonImpl(const std::filesystem::path&) override { return nullptr; } - Ref ImportAnimationImpl(const std::filesystem::path&, Ref targetSkeleton) override { return nullptr; } + bool ImportMeshImpl(const std::filesystem::path& path, Mesh& dstMesh) override; + bool ImportSkeletonImpl(const std::filesystem::path&, Skeleton& dstSkeleton) override { return false; } + bool ImportAnimationImpl(const std::filesystem::path&, Ref targetSkeleton, Animation& dstAnimation) override { return false; } private: bool IsValid(uint32_t subMeshCount, uint32_t vertexCount, uint32_t indexCount, size_t totalSize) const; diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp new file mode 100644 index 000000000..2295a850d --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.cpp @@ -0,0 +1,18 @@ +#include "vtpch.h" +#include "AssetSerializer.h" + +namespace Volt +{ + void AssetSerializer::WriteMetadata(const AssetMetadata& metadata, const uint32_t version, BinaryStreamWriter& streamWriter) + { + SerializedAssetMetadataHeader metadataHeader{}; + + SerializedAssetMetadata serializedMetadata{}; + serializedMetadata.handle = metadata.handle; + serializedMetadata.type = metadata.type; + serializedMetadata.version = version; + + streamWriter.Write(metadataHeader); + streamWriter.Write(serializedMetadata); + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h new file mode 100644 index 000000000..79b16ba33 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/AssetSerializer.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Volt/Asset/Asset.h" + +#include "Volt/Asset/Serialization/AssetSerializationCommon.h" + +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" + +namespace Volt +{ + class AssetSerializer + { + public: + virtual ~AssetSerializer() = default; + + virtual void Serialize(const AssetMetadata& metadata, const Ref& asset) const = 0; + virtual bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const = 0; + + static void WriteMetadata(const AssetMetadata& metadata, const uint32_t version, BinaryStreamWriter& streamWriter); + }; +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp new file mode 100644 index 000000000..f4c3ada8f --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.cpp @@ -0,0 +1,60 @@ +#include "vtpch.h" +#include "MeshImporter.h" + +#include "Volt/Asset/Mesh/Mesh.h" +#include "Volt/Asset/Mesh/Material.h" +#include "Volt/Asset/Serialization/AssetSerializationCommon.h" + +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" + +namespace Volt +{ + constexpr uint32_t CURRENT_ASSET_VERSION = 1; + + struct MeshSerializationData + { + AssetHandle materialHandle; + + uint32_t vertexCount; + std::vector vertices; + + uint32_t indexCount; + std::vector indices; + + glm::vec3 boundingSphereCenter; + float boundingSphereRadius; + + std::vector subMeshes; + + static void Serialize(BinaryStreamWriter& streamWriter, const MeshSerializationData& data) + { + streamWriter.Write(data.materialHandle); + streamWriter.Write(data.vertexCount); + streamWriter.Write(data.vertices); + streamWriter.Write(data.indexCount); + streamWriter.Write(data.indices); + streamWriter.Write(data.boundingSphereCenter); + streamWriter.Write(data.boundingSphereRadius); + streamWriter.Write(data.subMeshes); + } + }; + + void MeshImporter::Serialize(const AssetMetadata& metadata, const Ref& asset) const + { + Ref mesh = std::reinterpret_pointer_cast(asset); + + BinaryStreamWriter streamWriter{}; + AssetSerializer::WriteMetadata(metadata, CURRENT_ASSET_VERSION, streamWriter); + + MeshSerializationData serializationData; + + streamWriter.Write(static_cast(mesh->mySubMeshes.size())); + streamWriter.Write(mesh->myMaterial->handle); + streamWriter.Write(serializationData); + } + + bool MeshImporter::Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const + { + return false; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h new file mode 100644 index 000000000..2aab7a725 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/MeshImporter.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Volt/Asset/ImportersNew/AssetSerializer.h" + +namespace Volt +{ + class MeshImporter : public AssetSerializer + { + public: + void Serialize(const AssetMetadata& metadata, const Ref& asset) const override; + bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; + + private: + }; +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.cpp b/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.cpp new file mode 100644 index 000000000..6ec21f684 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.cpp @@ -0,0 +1,29 @@ +#include "vtpch.h" +#include "SourceMeshImporter.h" + +#include "Volt/Asset/AssetManager.h" +#include "Volt/Asset/Importers/MeshTypeImporter.h" + +namespace Volt +{ + bool SourceMeshImporter::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; + } + + Ref destinationMesh = std::reinterpret_pointer_cast(destinationAsset); + if (!MeshTypeImporter::ImportMesh(filePath, *destinationMesh)) + { + destinationAsset->SetFlag(AssetFlag::Invalid, true); + return false; + } + + return true; + } +} diff --git a/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.h b/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.h new file mode 100644 index 000000000..abb9a9b5f --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/ImportersNew/SourceMeshImporter.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Volt/Asset/ImportersNew/AssetSerializer.h" + +namespace Volt +{ + class SourceMeshImporter : public AssetSerializer + { + public: + void Serialize(const AssetMetadata& metadata, const Ref& asset) const override {} // Type is not serializable + bool Deserialize(const AssetMetadata& metadata, Ref destinationAsset) const override; + }; +} diff --git a/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h b/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h index b9f134017..b40c14a38 100644 --- a/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h +++ b/Volt/Volt/src/Volt/Asset/Mesh/Mesh.h @@ -57,6 +57,7 @@ namespace Volt friend class FbxImporter; friend class MeshCompiler; + friend class MeshImporter; friend class MeshExporterUtilities; friend class VTMeshImporter; friend class GLTFImporter; diff --git a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp new file mode 100644 index 000000000..6d60988ee --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.cpp @@ -0,0 +1,14 @@ +#include "vtpch.h" +#include "AssetSerializationCommon.h" + +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" + +namespace Volt +{ + void SerializedAssetMetadata::Serialize(BinaryStreamWriter& streamWriter, const SerializedAssetMetadata& data) + { + streamWriter.Write(data.handle); + streamWriter.Write(data.type); + streamWriter.Write(data.version); + } +} diff --git a/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h new file mode 100644 index 000000000..213254512 --- /dev/null +++ b/Volt/Volt/src/Volt/Asset/Serialization/AssetSerializationCommon.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Volt/Asset/Asset.h" + +namespace Volt +{ + class BinaryStreamWriter; + + struct SerializedAssetMetadata + { + AssetHandle handle; + AssetType type; + uint32_t version; + + static void Serialize(BinaryStreamWriter& streamWriter, const SerializedAssetMetadata& data); + }; + + struct SerializedAssetMetadataHeader + { + size_t assetMetadataSize; + }; +} diff --git a/Volt/Volt/src/Volt/Core/UUID.cpp b/Volt/Volt/src/Volt/Core/UUID.cpp index 678557dc9..92fb395bf 100644 --- a/Volt/Volt/src/Volt/Core/UUID.cpp +++ b/Volt/Volt/src/Volt/Core/UUID.cpp @@ -1,6 +1,8 @@ #include "vtpch.h" #include "UUID.h" +#include "Volt/Utility/FileIO/BinaryStreamWriter.h" + #include #include @@ -17,6 +19,11 @@ namespace Volt { } + void UUID::Serialize(BinaryStreamWriter& streamWriter, const UUID& data) + { + streamWriter.Write(data.myUUID); + } + UUID32::UUID32() : m_uuid(s_uniformDistribution32(s_engine32)) { diff --git a/Volt/Volt/src/Volt/Core/UUID.h b/Volt/Volt/src/Volt/Core/UUID.h index 393a93f76..2f8f5cb88 100644 --- a/Volt/Volt/src/Volt/Core/UUID.h +++ b/Volt/Volt/src/Volt/Core/UUID.h @@ -4,6 +4,7 @@ namespace Volt { + class BinaryStreamWriter; class UUID { @@ -17,6 +18,9 @@ namespace Volt ~UUID() = default; operator uint64_t() const { return myUUID; } + + static void Serialize(BinaryStreamWriter& streamWriter, const UUID& data); + private: uint64_t myUUID; }; diff --git a/Volt/Volt/src/Volt/Rendering/BoundingStructures.h b/Volt/Volt/src/Volt/Rendering/BoundingStructures.h index 234ca8793..3cd4ec32d 100644 --- a/Volt/Volt/src/Volt/Rendering/BoundingStructures.h +++ b/Volt/Volt/src/Volt/Rendering/BoundingStructures.h @@ -23,7 +23,6 @@ namespace Volt const glm::vec3& GetCenter() const override { return center; } const float GetRadius() const override { return radius; } - glm::vec3 center = 0.f; float radius = 0.f; }; diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp new file mode 100644 index 000000000..2afa78f48 --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.cpp @@ -0,0 +1,28 @@ +#include "vtpch.h" +#include "BinaryStreamWriter.h" + +namespace Volt +{ + void BinaryStreamWriter::WriteData(const void* data, const size_t size, const TypeHeader& typeHeader) + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + + const size_t writeSize = size + typeHeaderSize; + size_t currentOffset = m_data.size(); + m_data.resize(currentOffset + writeSize); + + memcpy_s(&m_data[currentOffset], writeSize, &typeHeader, typeHeaderSize); + currentOffset += typeHeaderSize; + + memcpy_s(&m_data[currentOffset], writeSize - typeHeaderSize, data, size); + } + + void BinaryStreamWriter::WriteData(const void* data, const size_t size) + { + const size_t writeSize = size; + size_t currentOffset = m_data.size(); + m_data.resize(currentOffset + writeSize); + + memcpy_s(&m_data[currentOffset], writeSize, data, size); + } +} diff --git a/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h new file mode 100644 index 000000000..8f990ecc8 --- /dev/null +++ b/Volt/Volt/src/Volt/Utility/FileIO/BinaryStreamWriter.h @@ -0,0 +1,211 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Volt +{ + class BinaryStreamWriter + { + public: + template + [[nodiscard]] const size_t GetBinarySizeOfType(const T& object) const; + + template<> [[nodiscard]] const size_t GetBinarySizeOfType(const std::string& object) const; + template [[nodiscard]] const size_t GetBinarySizeOfType(const std::vector& object) const; + template [[nodiscard]] const size_t GetBinarySizeOfType(const std::array& object) const; + template [[nodiscard]] const size_t GetBinarySizeOfType(const std::map& object) const; + template [[nodiscard]] const size_t GetBinarySizeOfType(const std::unordered_map& object) const; + + template + void Write(const T& data); + + template<> + void Write(const std::string& data); + + template + void Write(const std::vector& data); + + template + void Write(const std::array& data); + + template + void Write(const std::map& data); + + template + void Write(const std::unordered_map& data); + + [[nodiscard]] const size_t GetSize() const { return m_data.size(); } + + private: + struct TypeHeader + { + uint16_t baseTypeSize; + uint32_t totalTypeSize; + }; + + void WriteData(const void* data, const size_t size, const TypeHeader& typeHeader); + void WriteData(const void* data, const size_t size); + + std::vector m_data; + }; + + template + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const T& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + + if constexpr (std::is_trivial_v) + { + return sizeof(T) + typeHeaderSize; + } + + BinaryStreamWriter tempSerializer{}; + T::Serialize(tempSerializer, object); + + return tempSerializer.GetSize() + typeHeaderSize; + } + + template<> + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const std::string& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + return object.size() + typeHeaderSize; + } + + template + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const std::vector& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + return object.size() * sizeof(F) + typeHeaderSize; + } + + template + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const std::array& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + return COUNT * sizeof(F) + typeHeaderSize; + } + + template + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const std::map& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + return object.size() * sizeof(Key) + object.size() * sizeof(Value) + typeHeaderSize; + } + + template + inline const size_t BinaryStreamWriter::GetBinarySizeOfType(const std::unordered_map& object) const + { + constexpr size_t typeHeaderSize = sizeof(TypeHeader); + return object.size() * sizeof(Key) + object.size() * sizeof(Value) + typeHeaderSize; + } + + template + inline void BinaryStreamWriter::Write(const T& data) + { + constexpr size_t typeSize = sizeof(T); + + if constexpr (std::is_trivial()) + { + TypeHeader header{}; + header.baseTypeSize = typeSize; + header.totalTypeSize = typeSize; + + WriteData(&data, typeSize, header); + } + else + { + T::Serialize(*this, data); + } + } + + template<> + inline void BinaryStreamWriter::Write(const std::string& data) + { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::string); + header.totalTypeSize = static_cast(data.size()); + + WriteData(data.data(), data.size(), header); + } + + template + inline void BinaryStreamWriter::Write(const std::vector& data) + { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::vector); + header.totalTypeSize = static_cast(data.size() * sizeof(F)); + + if constexpr (std::is_trivial_v) + { + WriteData(data.data(), data.size() * sizeof(F), header); + } + else + { + for (const auto& obj : data) + { + F::Serialize(*this, obj); + } + } + } + + template + inline void BinaryStreamWriter::Write(const std::array& data) + { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::array); + header.totalTypeSize = COUNT * sizeof(F); + + if constexpr (std::is_trivial_v) + { + WriteData(data.data(), data.size() * sizeof(F), header); + } + else + { + for (const auto& obj : data) + { + F::Serialize(*this, obj); + } + } + } + + template + inline void BinaryStreamWriter::Write(const std::map& data) + { + TypeHeader header{}; + header.baseTypeSize = sizeof(std::map& data); + header.totalTypeSize = data.size() * sizeof(Key) + data.size() * sizeof(Value); + + for (const auto& [key, value] : data) + { + if constexpr (std::is_trivial_v) + { + WriteData(&key, sizeof(Key)); + } + else + { + Key::Serialize(*this, key); + } + + if constexpr (std::is_trivial_v) + { + WriteData(&value, sizeof(Value)); + } + else + { + Value::Serialize(*this, value); + } + } + + + } + + template + inline void BinaryStreamWriter::Write(const std::unordered_map& data) + { + } +} diff --git a/Volt/Volt/src/Volt/Utility/FileIO/YAMLStreamWriter.h b/Volt/Volt/src/Volt/Utility/FileIO/YAMLStreamWriter.h index e674262ac..d313ad344 100644 --- a/Volt/Volt/src/Volt/Utility/FileIO/YAMLStreamWriter.h +++ b/Volt/Volt/src/Volt/Utility/FileIO/YAMLStreamWriter.h @@ -24,8 +24,6 @@ namespace Volt template void SetKey(const K& key, const T& value); - - const bool WriteToDisk(); private: