From 8b8e29db3f242d2d631b779f2ab2143b37721e15 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Thu, 11 Jul 2024 15:07:54 -0400 Subject: [PATCH] Quake brushes are not deserialized correctly, meaning you can build navmesh without rebuilding the quake map first. --- Editor/src/ComponentsPanel/QuakeMapPanel.h | 2 +- Nuake/src/Resource/Serializable.h | 3 +++ Nuake/src/Scene/Components/QuakeMap.h | 19 ++++++++++++++++++- Nuake/src/Scene/Entities/Entity.cpp | 5 +++++ Nuake/src/Scene/Entities/Entity.h | 1 + Nuake/src/Scene/Scene.cpp | 9 +++++++++ Nuake/src/Scene/Systems/QuakeMapBuilder.cpp | 2 ++ 7 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Editor/src/ComponentsPanel/QuakeMapPanel.h b/Editor/src/ComponentsPanel/QuakeMapPanel.h index 29113868..228eb443 100644 --- a/Editor/src/ComponentsPanel/QuakeMapPanel.h +++ b/Editor/src/ComponentsPanel/QuakeMapPanel.h @@ -86,7 +86,7 @@ public: { for (auto& mesh : component.m_Brushes) { - if (mesh.HasComponent())\ + if (mesh.HasComponent()) { TransformComponent& transformComponent = mesh.GetComponent(); for (auto& mesh : mesh.GetComponent().ModelResource->GetMeshes()) diff --git a/Nuake/src/Resource/Serializable.h b/Nuake/src/Resource/Serializable.h index 423e25bb..0d0b45ff 100644 --- a/Nuake/src/Resource/Serializable.h +++ b/Nuake/src/Resource/Serializable.h @@ -66,6 +66,9 @@ p = j[#p]; \ #define DESERIALIZE_COMPONENT(c) \ if(j.contains(#c)) \ AddComponent().Deserialize(j[#c]); +#define POSTDESERIALIZE_COMPONENT(c) \ + if(HasComponent()) \ + GetComponent().PostDeserialize(*m_Scene); class ISerializable { diff --git a/Nuake/src/Scene/Components/QuakeMap.h b/Nuake/src/Scene/Components/QuakeMap.h index 7d3b0ead..4fe0c250 100644 --- a/Nuake/src/Scene/Components/QuakeMap.h +++ b/Nuake/src/Scene/Components/QuakeMap.h @@ -15,6 +15,8 @@ namespace Nuake { public: std::vector> m_Meshes; std::vector m_Brushes; + std::vector m_SerializedBrushIDs; + std::string Path; float ScaleFactor = 1.0f; bool HasCollisions = false; @@ -26,6 +28,7 @@ namespace Nuake { SERIALIZE_VAL(HasCollisions); SERIALIZE_VAL(Path); SERIALIZE_VAL(AutoRebuild); + for (uint32_t i = 0; i < std::size(m_Brushes); i++) { j["Brushes"][i] = m_Brushes[i].GetID(); @@ -46,11 +49,13 @@ namespace Nuake { this->AutoRebuild = j["AutoRebuild"]; } + m_Brushes.clear(); + if (j.contains("Brushes")) { for (auto& b : j["Brushes"]) { - //m_Brushes.push_back(Engine::GetCurrentScene()->GetEntityByID(b)); + m_SerializedBrushIDs.push_back(b); } } @@ -58,5 +63,17 @@ namespace Nuake { this->HasCollisions = j["HasCollisions"]; return true; } + + void PostDeserialize(Scene& scene) + { + m_Brushes.clear(); + + for (auto& b : m_SerializedBrushIDs) + { + m_Brushes.push_back(scene.GetEntityByID(b)); + } + + m_SerializedBrushIDs.clear(); + } }; } diff --git a/Nuake/src/Scene/Entities/Entity.cpp b/Nuake/src/Scene/Entities/Entity.cpp index ebcb3224..4c598afa 100644 --- a/Nuake/src/Scene/Entities/Entity.cpp +++ b/Nuake/src/Scene/Entities/Entity.cpp @@ -114,6 +114,11 @@ namespace Nuake return true; } + void Entity::PostDeserialize() + { + POSTDESERIALIZE_COMPONENT(QuakeMapComponent); + } + Entity::Entity(entt::entity handle, Scene* scene) { m_EntityHandle = handle; diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index 461b84ed..41461b1b 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -75,6 +75,7 @@ namespace Nuake json Serialize() override; bool Deserialize(const json& str); + void PostDeserialize(); Scene* GetScene() const { diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 44132b5c..979d36d1 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -557,6 +557,7 @@ namespace Nuake m_EditorCamera->Deserialize(j["m_EditorCamera"]); } + // TODO: Move this to post deserialize. auto view = m_Registry.view(); for (auto e : view) { @@ -569,6 +570,14 @@ namespace Nuake parentEntity.AddChild(entity); } + // This will turn the deserialized entity ids into actual Entities. + // This has to be done after the whole scene has been deserialized + // to make sure we can fetch the id in the scene. Otherwise, we could + m_Registry.each([this](auto e) { + auto entity = Entity{ e, this }; + entity.PostDeserialize(); + }); + return true; } diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index dac776eb..eb6873fa 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -382,6 +382,8 @@ namespace Nuake { ent.GetComponent().IsPrefab = true; QuakeMapComponent& quakeMapC = ent.GetComponent(); + quakeMapC.m_Brushes.clear(); + ScaleFactor = quakeMapC.ScaleFactor; Scene* m_Scene = ent.GetScene();