From b57839d0bd1a3da38d46788e9032a71a8eb05efc Mon Sep 17 00:00:00 2001 From: JC Date: Sun, 8 Sep 2024 18:10:45 -0700 Subject: [PATCH] terrain loading in parallel --- engine/renderer/builder/fastgltfBuilder.cpp | 1 - engine/renderer/builder/terrainBuilder.cpp | 1 - engine/scene/sceneLoaderDeserializeJSON.cpp | 75 +++++++++++++------ engine/scene/sceneLoaderJSON.h | 14 +++- engine/scene/terrainLoaderDeserializeJSON.cpp | 2 +- engine/scene/terrainLoaderJSON.h | 2 +- 6 files changed, 68 insertions(+), 27 deletions(-) diff --git a/engine/renderer/builder/fastgltfBuilder.cpp b/engine/renderer/builder/fastgltfBuilder.cpp index f6037b81..c0fb52a3 100644 --- a/engine/renderer/builder/fastgltfBuilder.cpp +++ b/engine/renderer/builder/fastgltfBuilder.cpp @@ -543,7 +543,6 @@ namespace GfxRenderEngine { LOG_CORE_CRITICAL("not supported default branch " + glTFImage.name); }, }, glTFImage.data); - LOG_CORE_INFO("loadTexture end, image index: {0}", imageIndex); return texture; }; futures[imageIndex] = Engine::m_Engine->m_PoolSecondary.SubmitTask(loadtexture); diff --git a/engine/renderer/builder/terrainBuilder.cpp b/engine/renderer/builder/terrainBuilder.cpp index 88b13557..212e5cf0 100644 --- a/engine/renderer/builder/terrainBuilder.cpp +++ b/engine/renderer/builder/terrainBuilder.cpp @@ -28,7 +28,6 @@ #include "renderer/builder/terrainBuilder.h" #include "auxiliary/file.h" #include "scene/scene.h" -#include "auxiliary/debug.h" namespace GfxRenderEngine { diff --git a/engine/scene/sceneLoaderDeserializeJSON.cpp b/engine/scene/sceneLoaderDeserializeJSON.cpp index ecd81242..524d6b73 100644 --- a/engine/scene/sceneLoaderDeserializeJSON.cpp +++ b/engine/scene/sceneLoaderDeserializeJSON.cpp @@ -87,9 +87,13 @@ namespace GfxRenderEngine } } + m_TerrainInfos.resize(terrainDescriptions.count_elements()); + uint terrainCounter = 0; for (auto terrainDescription : terrainDescriptions) { - ParseTerrainDescription(terrainDescription, m_SceneDescriptionFile.m_TerrainDescriptions); + ParseTerrainDescription(terrainDescription, m_SceneDescriptionFile.m_TerrainDescriptions, + m_TerrainInfos[terrainCounter]); + ++terrainCounter; } } @@ -280,6 +284,7 @@ namespace GfxRenderEngine LOG_CORE_CRITICAL("unrecognized scene object '" + std::string(sceneObjectKey) + "'"); } } + FinalizeTerrainDescriptions(); } void SceneLoaderJSON::ParseGltfFile(ondemand::object gltfFileJSON, bool fast, SceneLoaderJSON::GltfInfo& gltfInfo) @@ -622,7 +627,8 @@ namespace GfxRenderEngine } void SceneLoaderJSON::ParseTerrainDescription(ondemand::object terrainDescription, - std::vector& terrainDescriptions) + std::vector& terrainDescriptions, + TerrainInfo& terrainInfo) { std::string filename; @@ -656,32 +662,21 @@ namespace GfxRenderEngine return; } - TerrainLoaderJSON terrainLoaderJSON(m_Scene); - bool loadSuccessful = terrainLoaderJSON.Deserialize(filename, instanceCount); - - if (!loadSuccessful) + auto loadTerrain = [this, filename, instanceCount]() { - LOG_CORE_CRITICAL("terrain description did not load properly: {0}", filename); - return; - } + TerrainLoaderJSON terrainLoaderJSON(m_Scene); + return terrainLoaderJSON.Deserialize(filename, instanceCount); + }; - Terrain::TerrainDescription terrainDescriptionScene(filename); - terrainDescriptions.push_back(terrainDescriptionScene); - - std::vector& terrainInstances = terrainDescriptions.back().m_Instances; - terrainInstances.resize(instanceCount); + terrainInfo.m_LoadFuture = Engine::m_Engine->m_PoolPrimary.SubmitTask(loadTerrain); + terrainInfo.m_Filename = filename; + terrainInfo.m_InstanceCount = instanceCount; + terrainInfo.m_InstanceTransforms.resize(instanceCount); { - auto name = EngineCore::GetFilenameWithoutPath(filename); - name = EngineCore::GetFilenameWithoutExtension(name); uint instanceIndex = 0; for (auto instance : instances) { - std::string entityName = name + std::string("::" + std::to_string(instanceIndex)); - entt::entity entity = m_Scene.m_Dictionary.Retrieve(entityName); - CORE_ASSERT(entity != entt::null, "couldn't find entity"); - Terrain::Instance& terrainInstance = terrainInstances[instanceIndex]; - terrainInstance.m_Entity = entity; ondemand::object instanceObjects = instance.value(); for (auto instanceObject : instanceObjects) { @@ -691,7 +686,7 @@ namespace GfxRenderEngine { CORE_ASSERT((instanceObject.value().type() == ondemand::json_type::object), "type must be object"); - TransformComponent& transform = m_Scene.m_Registry.get(entity); + TransformComponent& transform = terrainInfo.m_InstanceTransforms[instanceIndex]; ParseTransform(instanceObject.value(), transform); } else @@ -714,4 +709,40 @@ namespace GfxRenderEngine { return m_SceneDescriptionFile.m_TerrainDescriptions; } + + void SceneLoaderJSON::FinalizeTerrainDescriptions() + { + for (auto& terrainInfo : m_TerrainInfos) + { + if (!terrainInfo.m_LoadFuture.get()) + { + continue; + } + Terrain::TerrainDescription terrainDescriptionScene(terrainInfo.m_Filename); + m_SceneDescriptionFile.m_TerrainDescriptions.push_back(terrainDescriptionScene); + + std::vector& terrainInstances = + m_SceneDescriptionFile.m_TerrainDescriptions.back().m_Instances; + terrainInstances.resize(terrainInfo.m_InstanceCount); + + { + auto name = EngineCore::GetFilenameWithoutPath(terrainInfo.m_Filename); + name = EngineCore::GetFilenameWithoutExtension(name); + uint instanceIndex = 0; + for (auto& terrainInstance : terrainInstances) + { + std::string entityName = name + std::string("::" + std::to_string(instanceIndex)); + entt::entity entity = m_Scene.m_Dictionary.Retrieve(entityName); + CORE_ASSERT(entity != entt::null, "couldn't find entity"); + terrainInstance.m_Entity = entity; + TransformComponent& transform = m_Scene.m_Registry.get(entity); + transform.SetScale(terrainInfo.m_InstanceTransforms[instanceIndex].GetScale()); + transform.SetRotation(terrainInfo.m_InstanceTransforms[instanceIndex].GetRotation()); + transform.SetTranslation(terrainInfo.m_InstanceTransforms[instanceIndex].GetTranslation()); + + ++instanceIndex; + } + } + } + } } // namespace GfxRenderEngine diff --git a/engine/scene/sceneLoaderJSON.h b/engine/scene/sceneLoaderJSON.h index c06450ad..8324afa8 100644 --- a/engine/scene/sceneLoaderJSON.h +++ b/engine/scene/sceneLoaderJSON.h @@ -74,6 +74,14 @@ namespace GfxRenderEngine std::vector m_InstanceTransforms; }; + struct TerrainInfo + { + std::future m_LoadFuture; + std::string m_Filename; + int m_InstanceCount{0}; + std::vector m_InstanceTransforms; + }; + private: void Deserialize(std::string& filepath); @@ -84,7 +92,9 @@ namespace GfxRenderEngine void ParseNodesGltf(ondemand::array nodesJSON, std::string const& gltfFilename, Gltf::Instance& gltfFileInstance, uint instanceIndex); void ParseTerrainDescription(ondemand::object terrainDescription, - std::vector& terrainDescriptions); + std::vector& terrainDescriptions, + TerrainInfo& terrainInfo); + void FinalizeTerrainDescriptions(); glm::vec3 ConvertToVec3(ondemand::array arrayJSON); @@ -131,5 +141,7 @@ namespace GfxRenderEngine Scene& m_Scene; SceneDescriptionFile m_SceneDescriptionFile; + + std::vector m_TerrainInfos; }; } // namespace GfxRenderEngine diff --git a/engine/scene/terrainLoaderDeserializeJSON.cpp b/engine/scene/terrainLoaderDeserializeJSON.cpp index 8544b79f..fb10a6cb 100644 --- a/engine/scene/terrainLoaderDeserializeJSON.cpp +++ b/engine/scene/terrainLoaderDeserializeJSON.cpp @@ -29,7 +29,7 @@ namespace GfxRenderEngine TerrainLoaderJSON::TerrainLoaderJSON(Scene& scene) : m_Scene(scene) {} - bool TerrainLoaderJSON::Deserialize(std::string& filepath, int instanceCount) + bool TerrainLoaderJSON::Deserialize(std::string filepath, int instanceCount) { if (!EngineCore::FileExists(filepath)) { diff --git a/engine/scene/terrainLoaderJSON.h b/engine/scene/terrainLoaderJSON.h index 06b4885d..15f76afb 100644 --- a/engine/scene/terrainLoaderJSON.h +++ b/engine/scene/terrainLoaderJSON.h @@ -41,7 +41,7 @@ namespace GfxRenderEngine TerrainLoaderJSON(Scene& scene); ~TerrainLoaderJSON() {} - bool Deserialize(std::string& filepath, int instanceCount); + bool Deserialize(std::string filepath, int instanceCount); private: struct TerrainDescriptionFile