From 2369c9d212322714754d488135c8d9f6fbf28c4e Mon Sep 17 00:00:00 2001 From: QuestionableM <77170113+QuestionableM@users.noreply.github.com> Date: Sat, 14 May 2022 09:15:05 -0700 Subject: [PATCH] Moved loaders into separate files --- Blueprint Converter.vcxproj | 4 + Blueprint Converter.vcxproj.filters | 4 + Code/Gui/About.h | 2 +- Code/Lib/BuildVersion.h | 2 +- Code/Lib/Json.cpp | 36 -- .../DataLoaders/BlockListLoader.cpp | 91 +++++ .../DataLoaders/BlockListLoader.h | 23 ++ .../DataLoaders/PartListLoader.cpp | 235 +++++++++++++ .../DataLoaders/PartListLoader.h | 31 ++ Code/ObjectDatabase/ModData.cpp | 323 ++---------------- Code/ObjectDatabase/ModData.h | 19 +- Code/ObjectDatabase/ObjectData.cpp | 8 +- Code/ObjectDatabase/ObjectData.h | 6 +- 13 files changed, 425 insertions(+), 359 deletions(-) create mode 100644 Code/ObjectDatabase/DataLoaders/BlockListLoader.cpp create mode 100644 Code/ObjectDatabase/DataLoaders/BlockListLoader.h create mode 100644 Code/ObjectDatabase/DataLoaders/PartListLoader.cpp create mode 100644 Code/ObjectDatabase/DataLoaders/PartListLoader.h diff --git a/Blueprint Converter.vcxproj b/Blueprint Converter.vcxproj index 0f1d7c8..8437bbd 100644 --- a/Blueprint Converter.vcxproj +++ b/Blueprint Converter.vcxproj @@ -44,6 +44,8 @@ + + @@ -96,6 +98,8 @@ + + diff --git a/Blueprint Converter.vcxproj.filters b/Blueprint Converter.vcxproj.filters index f477022..5c9c44e 100644 --- a/Blueprint Converter.vcxproj.filters +++ b/Blueprint Converter.vcxproj.filters @@ -35,6 +35,8 @@ + + @@ -77,5 +79,7 @@ + + \ No newline at end of file diff --git a/Code/Gui/About.h b/Code/Gui/About.h index a61b1f7..61038df 100644 --- a/Code/Gui/About.h +++ b/Code/Gui/About.h @@ -102,7 +102,7 @@ namespace BlueprintConverter { this->Version_LBL->Name = L"Version_LBL"; this->Version_LBL->Size = System::Drawing::Size(86, 16); this->Version_LBL->TabIndex = 6; - this->Version_LBL->Text = L"Version: 1.1.1"; + this->Version_LBL->Text = L"Version: 1.1.2"; this->Version_LBL->TextAlign = System::Drawing::ContentAlignment::MiddleLeft; // // GitHubRepo_LL diff --git a/Code/Lib/BuildVersion.h b/Code/Lib/BuildVersion.h index 7441e93..b378257 100644 --- a/Code/Lib/BuildVersion.h +++ b/Code/Lib/BuildVersion.h @@ -1,2 +1,2 @@ #pragma once -#define SMBC_BUILD_VERSION 858 \ No newline at end of file +#define SMBC_BUILD_VERSION 863 \ No newline at end of file diff --git a/Code/Lib/Json.cpp b/Code/Lib/Json.cpp index d988ab7..5c1b539 100644 --- a/Code/Lib/Json.cpp +++ b/Code/Lib/Json.cpp @@ -72,42 +72,6 @@ namespace SMBC #endif return nlohmann::json(); - /*try - { - std::ifstream _InputFile(path); - if (_InputFile.is_open()) - { - std::string _RawJson; - - if (_stringify) - _RawJson = Json::ReadWholeFile(_InputFile); - else - { - std::stringstream sstream; - - sstream << _InputFile.rdbuf(); - _RawJson = sstream.str(); - } - - return nlohmann::json::parse(_RawJson, nullptr, true, true); - } - #ifdef _DEBUG - else - { - DebugErrorL("Couldn't open the specified file: ", path); - } - #endif - } - #ifdef _DEBUG - catch (nlohmann::json::parse_error& err) - { - DebugErrorL("Couldn't load the specified json file:\nFile: ", path, "\nByte: ", err.byte, "\nId: ", err.id, "\nError Message: ", err.what()); - } - #else - catch (...) {} - #endif - - return nlohmann::json();*/ } void Json::WriteToFile(const std::wstring& path, const nlohmann::json& mJson) diff --git a/Code/ObjectDatabase/DataLoaders/BlockListLoader.cpp b/Code/ObjectDatabase/DataLoaders/BlockListLoader.cpp new file mode 100644 index 0000000..cae75ac --- /dev/null +++ b/Code/ObjectDatabase/DataLoaders/BlockListLoader.cpp @@ -0,0 +1,91 @@ +#include "BlockListLoader.h" + +#include "ObjectDatabase\ModData.h" +#include "ObjectDatabase\KeywordReplacer.h" + +#include "Lib\ConvData.h" +#include "Lib\String.h" +#include "Lib\Json.h" + +#include "DebugCon.h" + +namespace SMBC +{ + void BlockListLoader::GetBlockMaterials(const nlohmann::json& block, Texture::TextureList& tex) + { + const auto& bGlass = Json::Get(block, "glass"); + const auto& bAlpha = Json::Get(block, "alpha"); + + if (bGlass.is_boolean() && bGlass.get()) + { + tex.material = L"BlockGlass"; + } + else + { + tex.material = L"BlockDifAsgNor"; + + if (bAlpha.is_boolean() && bAlpha.get()) + tex.material.append(L"Alpha"); + } + } + + static const std::string blkTexNames[3] = { "dif", "asg", "nor" }; + bool BlockListLoader::GetBlockTextures(const nlohmann::json& block, Texture::TextureList& tex) + { + for (int a = 0; a < 3; a++) + { + const auto& bTexture = Json::Get(block, blkTexNames[a]); + + if (bTexture.is_string()) + { + std::wstring& strRef = tex.GetStringRef(a); + + strRef = String::ToWide(bTexture.get()); + strRef = PathReplacer::ReplaceKey(strRef); + } + } + + return tex.HasTextures(); + } + + void BlockListLoader::Load(const nlohmann::json& block_list, Mod* pMod) + { + ConvData::ProgressMax += block_list.size(); + for (const auto& l_block : block_list) + { + if (!l_block.is_object()) continue; + + const auto& b_uuid = Json::Get(l_block, "uuid"); + if (!b_uuid.is_string()) continue; + + const auto& b_tiling = Json::Get(l_block, "tiling"); + const auto& b_color = Json::Get(l_block, "color"); + + SMBC::Uuid uuid_obj(b_uuid.get()); + if (Mod::AllObjects.find(uuid_obj) != Mod::AllObjects.end()) + { + DebugWarningL("An object with this uuid already exists! (", uuid_obj.ToString(), ")"); + continue; + } + + Texture::TextureList tex_list; + if (!BlockListLoader::GetBlockTextures(l_block, tex_list)) + continue; + + BlockListLoader::GetBlockMaterials(l_block, tex_list); + + int tiling_val = (b_tiling.is_number() ? b_tiling.get() : 4); + if (tiling_val > 16 || tiling_val <= 0) tiling_val = 4; + + const std::wstring l_NameWstr = pMod->m_LanguageDb.GetTranslation(uuid_obj); + + BlockData* p_new_blk = new BlockData(uuid_obj, l_NameWstr, tex_list, tiling_val, pMod); + + const auto new_pair = std::make_pair(p_new_blk->Uuid, p_new_blk); + Mod::AllObjects.insert(new_pair); + pMod->m_Objects.insert(new_pair); + + ConvData::ProgressValue++; + } + } +} \ No newline at end of file diff --git a/Code/ObjectDatabase/DataLoaders/BlockListLoader.h b/Code/ObjectDatabase/DataLoaders/BlockListLoader.h new file mode 100644 index 0000000..02f2fd9 --- /dev/null +++ b/Code/ObjectDatabase/DataLoaders/BlockListLoader.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace SMBC +{ + namespace Texture + { + struct TextureList; + } + + class BlockListLoader + { + BlockListLoader() = default; + ~BlockListLoader() = default; + + static void GetBlockMaterials(const nlohmann::json& block, Texture::TextureList& tex); + static bool GetBlockTextures(const nlohmann::json& block, Texture::TextureList& tex); + + public: + static void Load(const nlohmann::json& block_list, class Mod* pMod); + }; +} \ No newline at end of file diff --git a/Code/ObjectDatabase/DataLoaders/PartListLoader.cpp b/Code/ObjectDatabase/DataLoaders/PartListLoader.cpp new file mode 100644 index 0000000..8e026f9 --- /dev/null +++ b/Code/ObjectDatabase/DataLoaders/PartListLoader.cpp @@ -0,0 +1,235 @@ +#include "PartListLoader.h" + +#include "ObjectDatabase\ModData.h" +#include "ObjectDatabase\KeywordReplacer.h" + +#include "Lib\Json.h" +#include "Lib\String.h" +#include "Lib\ConvData.h" + +#include "DebugCon.h" + +namespace SMBC +{ + void PartListLoader::LoadTextureList(const nlohmann::json& texList, Texture::TextureList& entry) + { + const int arr_sz = (int)texList.size(); + const int list_sz = (arr_sz > 3 ? 3 : arr_sz); + + for (int a = 0; a < list_sz; a++) + { + const auto& cur_item = texList.at(a); + + if (cur_item.is_string()) + { + std::wstring& wstr_path = entry.GetStringRef(a); + + wstr_path = String::ToWide(cur_item.get()); + wstr_path = PathReplacer::ReplaceKey(wstr_path); + } + } + } + + void PartListLoader::AddSubMesh(const nlohmann::json& subMesh, Texture::Texture& tex, const std::wstring& idx) + { + const auto& sTexList = Json::Get(subMesh, "textureList"); + if (!sTexList.is_array()) return; + + Texture::TextureList new_entry; + PartListLoader::LoadTextureList(sTexList, new_entry); + + const auto& sMaterial = Json::Get(subMesh, "material"); + new_entry.material = (sMaterial.is_string() ? String::ToWide(sMaterial.get()) : L"DifAsgNor"); + + tex.AddEntry(idx, new_entry); + } + + bool PartListLoader::TryLoadSubMeshList(const nlohmann::json& pLodItem, Texture::Texture& tex) + { + const auto& pMeshList = Json::Get(pLodItem, "subMeshList"); + if (!pMeshList.is_array()) return false; + + std::size_t _idx = 0; + Texture::Texture out_tex(Texture::TextureType::SubMeshList); + for (const auto& subMesh : pMeshList) + { + if (!subMesh.is_object()) continue; + + const auto& sIdx = Json::Get(subMesh, "idx"); + std::size_t cur_idx = (sIdx.is_number() ? sIdx.get() : _idx); + + PartListLoader::AddSubMesh(subMesh, out_tex, std::to_wstring(cur_idx)); + _idx++; + } + + tex = out_tex; + return true; + } + + bool PartListLoader::TryLoadSubMeshMap(const nlohmann::json& pLodItem, Texture::Texture& tex) + { + const auto& pMeshMap = Json::Get(pLodItem, "subMeshMap"); + if (!pMeshMap.is_object()) return false; + + Texture::Texture out_tex(Texture::TextureType::SubMeshMap); + for (const auto& subMesh : pMeshMap.items()) + { + if (!subMesh.value().is_object()) continue; + + std::wstring subMeshName = String::ToWide(subMesh.key()); + PartListLoader::AddSubMesh(subMesh.value(), out_tex, subMeshName); + } + + tex = out_tex; + return true; + } + + bool PartListLoader::LoadSubMeshes(const nlohmann::json& pLodItem, Texture::Texture& tex) + { + if (PartListLoader::TryLoadSubMeshList(pLodItem, tex) || PartListLoader::TryLoadSubMeshMap(pLodItem, tex)) + return true; + + return false; + } + + bool PartListLoader::LoadRenderable(const nlohmann::json& pRenderable, Texture::Texture& tex_data, std::wstring& mesh_path) + { + const auto& rLodList = Json::Get(pRenderable, "lodList"); + if (!rLodList.is_array() || rLodList.size() == 0) return false; + + const auto& rLodItem = Json::Get(rLodList, 0); + if (!rLodItem.is_object()) return false; + + const auto& rMesh = Json::Get(rLodItem, "mesh"); + if (!rMesh.is_string()) return false; + + mesh_path = String::ToWide(rMesh.get()); + mesh_path = PathReplacer::ReplaceKey(mesh_path); + + return PartListLoader::LoadSubMeshes(rLodItem, tex_data); + } + + bool PartListLoader::GetRenderableData(const nlohmann::json& part, Texture::Texture& tex_data, std::wstring& mesh_path) + { + const auto& pRenderable = Json::Get(part, "renderable"); + + nlohmann::json rend_data; + switch (pRenderable.type()) + { + case nlohmann::detail::value_t::string: + { + const std::wstring p_rend_wide = String::ToWide(pRenderable.get()); + const std::wstring p_rend_repl = PathReplacer::ReplaceKey(p_rend_wide); + + rend_data = Json::LoadParseJson(p_rend_repl); + if (!rend_data.is_object()) + return false; + + break; + } + case nlohmann::detail::value_t::object: + rend_data = pRenderable; + break; + default: + return false; + } + + return PartListLoader::LoadRenderable(rend_data, tex_data, mesh_path); + } + + glm::vec3 PartListLoader::LoadPartCollision(const nlohmann::json& collision) + { + const bool isBoxCol = collision.contains("box"); + const bool isHullCol = collision.contains("hull"); + if (isBoxCol || isHullCol) + { + const auto& b_Col = collision.at(isBoxCol ? "box" : "hull"); + + if (b_Col.is_object()) + { + const auto& xPos = Json::Get(b_Col, "x"); + const auto& yPos = Json::Get(b_Col, "y"); + const auto& zPos = Json::Get(b_Col, "z"); + + if (xPos.is_number() && yPos.is_number() && zPos.is_number()) + return { xPos.get(), yPos.get(), zPos.get() }; + } + } + else + { + const auto& cyl_col = Json::Get(collision, "cylinder"); + if (cyl_col.is_object()) + { + const auto& c_Diameter = Json::Get(cyl_col, "diameter"); + const auto& c_Depth = Json::Get(cyl_col, "depth"); + + if (c_Diameter.is_number() && c_Depth.is_number()) + { + const float f_Diameter = c_Diameter.get(); + const float f_Depth = c_Depth.get(); + + const auto& c_Axis = Json::Get(cyl_col, "axis"); + const std::string c_AxisStr = (c_Axis.is_string() ? c_Axis.get() : "z"); + + switch (c_AxisStr[0]) + { + case 'x': case 'X': + return { f_Depth, f_Diameter, f_Diameter }; + case 'y': case 'Y': + return { f_Diameter, f_Depth, f_Diameter }; + case 'z': case 'Z': + return { f_Diameter, f_Diameter, f_Depth }; + } + } + } + else + { + const auto& sphere_col = Json::Get(collision, "sphere"); + if (sphere_col.is_object()) + { + const auto& s_Diameter = Json::Get(sphere_col, "diameter"); + if (s_Diameter.is_number()) + return glm::vec3(s_Diameter.get()); + } + } + } + + return glm::vec3(1.0f); + } + + void PartListLoader::Load(const nlohmann::json& part_list, Mod* pMod) + { + ConvData::ProgressMax += part_list.size(); + for (const auto& l_part : part_list) + { + if (!l_part.is_object()) continue; + + const auto& p_uuid = Json::Get(l_part, "uuid"); + if (!p_uuid.is_string()) continue; + + SMBC::Uuid uuid_obj(p_uuid.get()); + + if (Mod::AllObjects.find(uuid_obj) != Mod::AllObjects.end()) + { + DebugWarningL("An object with this uuid already exists! (", uuid_obj.ToString(), ")"); + continue; + } + + std::wstring mesh_path; + Texture::Texture tex_data; + if (!PartListLoader::GetRenderableData(l_part, tex_data, mesh_path)) + continue; + + const std::wstring l_NameWstr = pMod->m_LanguageDb.GetTranslation(uuid_obj); + const glm::vec3 p_bounds = PartListLoader::LoadPartCollision(l_part); + + PartData* p_new_part = new PartData(uuid_obj, mesh_path, l_NameWstr, tex_data, p_bounds, pMod); + + const auto new_pair = std::make_pair(p_new_part->Uuid, p_new_part); + Mod::AllObjects.insert(new_pair); + pMod->m_Objects.insert(new_pair); + + ConvData::ProgressValue++; + } + } +} \ No newline at end of file diff --git a/Code/ObjectDatabase/DataLoaders/PartListLoader.h b/Code/ObjectDatabase/DataLoaders/PartListLoader.h new file mode 100644 index 0000000..adea907 --- /dev/null +++ b/Code/ObjectDatabase/DataLoaders/PartListLoader.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace SMBC +{ + namespace Texture + { + class Texture; + struct TextureList; + } + + class PartListLoader + { + PartListLoader() = default; + ~PartListLoader() = default; + + static void LoadTextureList(const nlohmann::json& texList, Texture::TextureList& entry); + static void AddSubMesh(const nlohmann::json& subMesh, Texture::Texture& tex, const std::wstring& idx); + static bool TryLoadSubMeshList(const nlohmann::json& pLodItem, Texture::Texture& tex); + static bool TryLoadSubMeshMap(const nlohmann::json& pLodItem, Texture::Texture& tex); + static bool LoadSubMeshes(const nlohmann::json& pLodItem, Texture::Texture& tex); + static bool LoadRenderable(const nlohmann::json& pRenderable, Texture::Texture& tex_data, std::wstring& mesh_path); + static bool GetRenderableData(const nlohmann::json& part, Texture::Texture& tex_data, std::wstring& mesh_path); + static glm::vec3 LoadPartCollision(const nlohmann::json& collision); + + public: + static void Load(const nlohmann::json& part_list, class Mod* pMod); + }; +} \ No newline at end of file diff --git a/Code/ObjectDatabase/ModData.cpp b/Code/ObjectDatabase/ModData.cpp index e8e9c66..bd50306 100644 --- a/Code/ObjectDatabase/ModData.cpp +++ b/Code/ObjectDatabase/ModData.cpp @@ -3,6 +3,9 @@ #include "ObjectDatabase\KeywordReplacer.h" #include "ObjectDatabase\DatabaseLoader.h" +#include "ObjectDatabase\DataLoaders\BlockListLoader.h" +#include "ObjectDatabase\DataLoaders\PartListLoader.h" + #include "Lib\ConvData.h" #include "Lib\String.h" #include "Lib\File.h" @@ -15,320 +18,35 @@ namespace fs = std::filesystem; namespace SMBC { - void Mod::GetBlockMaterials(const nlohmann::json& block, Texture::TextureList& tex) - { - const auto& bGlass = Json::Get(block, "glass"); - const auto& bAlpha = Json::Get(block, "alpha"); - - if (bGlass.is_boolean() && bGlass.get()) - { - tex.material = L"BlockGlass"; - } - else - { - tex.material = L"BlockDifAsgNor"; - - if (bAlpha.is_boolean() && bAlpha.get()) - tex.material.append(L"Alpha"); - } - } - - static const std::string blkTexNames[3] = { "dif", "asg", "nor" }; - bool Mod::GetBlockTextures(const nlohmann::json& block, Texture::TextureList& tex) - { - for (int a = 0; a < 3; a++) - { - const auto& bTexture = Json::Get(block, blkTexNames[a]); - - if (bTexture.is_string()) - { - std::wstring& strRef = tex.GetStringRef(a); - - strRef = String::ToWide(bTexture.get()); - strRef = PathReplacer::ReplaceKey(strRef); - } - } - - return tex.HasTextures(); - } - - void Mod::LoadBlocks(const nlohmann::json& fJson) - { - const auto& bList = Json::Get(fJson, "blockList"); - if (!bList.is_array()) return; - - ConvData::ProgressMax += bList.size(); - for (const auto& lBlock : bList) - { - const auto& bUuid = Json::Get(lBlock, "uuid"); - const auto& bTiling = Json::Get(lBlock, "tiling"); - const auto& bColor = Json::Get(lBlock, "color"); - - if (!bUuid.is_string()) continue; - - SMBC::Uuid uuid_obj(bUuid.get()); - - if (AllObjects.find(uuid_obj) != AllObjects.end()) - { - DebugWarningL("An object with this uuid already exists! (", uuid_obj.ToString(), ")"); - continue; - } - - Texture::TextureList tex_list; - if (!Mod::GetBlockTextures(lBlock, tex_list)) continue; - Mod::GetBlockMaterials(lBlock, tex_list); - - int tiling_value = (bTiling.is_number() ? bTiling.get() : 4); - if (tiling_value > 16 || tiling_value <= 0) tiling_value = 4; - - const std::wstring l_NameWstr = m_LanguageDb.GetTranslation(uuid_obj); - - BlockData* new_blk = new BlockData(uuid_obj, l_NameWstr, tex_list, tiling_value); - new_blk->ModPtr = this; - - const auto new_pair = std::make_pair(new_blk->Uuid, new_blk); - Mod::AllObjects.insert(new_pair); - m_Objects.insert(new_pair); - - ConvData::ProgressValue++; - } - } - - void Mod::LoadTextureList(const nlohmann::json& texList, Texture::TextureList& entry) - { - const int arr_sz = (int)texList.size(); - const int list_sz = (arr_sz > 3 ? 3 : arr_sz); - - for (int a = 0; a < list_sz; a++) - { - const auto& cur_item = texList.at(a); - - if (cur_item.is_string()) - { - std::wstring& wstr_path = entry.GetStringRef(a); - - wstr_path = String::ToWide(cur_item.get()); - wstr_path = PathReplacer::ReplaceKey(wstr_path); - } - } - } - - void Mod::AddSubMesh(const nlohmann::json& subMesh, Texture::Texture& tex, const std::wstring& idx) - { - const auto& sTexList = Json::Get(subMesh, "textureList"); - if (!sTexList.is_array()) return; - - Texture::TextureList new_entry; - Mod::LoadTextureList(sTexList, new_entry); - - const auto& sMaterial = Json::Get(subMesh, "material"); - new_entry.material = (sMaterial.is_string() ? String::ToWide(sMaterial.get()) : L"DifAsgNor"); - - tex.AddEntry(idx, new_entry); - } - - bool Mod::TryLoadSubMeshList(const nlohmann::json& pLodItem, Texture::Texture& tex) - { - const auto& pMeshList = Json::Get(pLodItem, "subMeshList"); - if (!pMeshList.is_array()) return false; - - std::size_t _idx = 0; - Texture::Texture out_tex(Texture::TextureType::SubMeshList); - for (const auto& subMesh : pMeshList) - { - if (!subMesh.is_object()) continue; - - const auto& sIdx = Json::Get(subMesh, "idx"); - std::size_t cur_idx = (sIdx.is_number() ? sIdx.get() : _idx); - - Mod::AddSubMesh(subMesh, out_tex, std::to_wstring(cur_idx)); - _idx++; - } - - tex = out_tex; - return true; - } - - bool Mod::TryLoadSubMeshMap(const nlohmann::json& pLodItem, Texture::Texture& tex) - { - const auto& pMeshMap = Json::Get(pLodItem, "subMeshMap"); - if (!pMeshMap.is_object()) return false; - - Texture::Texture out_tex(Texture::TextureType::SubMeshMap); - for (const auto& subMesh : pMeshMap.items()) - { - if (!subMesh.value().is_object()) continue; - - std::wstring subMeshName = String::ToWide(subMesh.key()); - Mod::AddSubMesh(subMesh.value(), out_tex, subMeshName); - } - - tex = out_tex; - return true; - } - - bool Mod::LoadSubMeshes(const nlohmann::json& pLodItem, Texture::Texture& tex) + const static std::unordered_map m_DataLoaders = { - if (Mod::TryLoadSubMeshList(pLodItem, tex) || Mod::TryLoadSubMeshMap(pLodItem, tex)) - return true; - - return false; - } - - bool Mod::LoadRenderable(const nlohmann::json& pRenderable, Texture::Texture& tex_data, std::wstring& mesh_path) - { - const auto& rLodList = Json::Get(pRenderable, "lodList"); - if (!rLodList.is_array() || rLodList.size() == 0) return false; - - const auto& rLodItem = Json::Get(rLodList, 0); - if (!rLodItem.is_object()) return false; - - const auto& rMesh = Json::Get(rLodItem, "mesh"); - if (!rMesh.is_string()) return false; - - mesh_path = String::ToWide(rMesh.get()); - mesh_path = PathReplacer::ReplaceKey(mesh_path); - - return Mod::LoadSubMeshes(rLodItem, tex_data); - } + { "blockList", BlockListLoader::Load }, + { "partList" , PartListLoader::Load } + }; - bool Mod::GetRenderableData(const nlohmann::json& part, Texture::Texture& tex_data, std::wstring& mesh_path) + void Mod::LoadObjectFile(const std::wstring& path) { - const auto& pRenderable = Json::Get(part, "renderable"); - - nlohmann::json rend_data; - if (pRenderable.is_string()) - { - std::wstring pRendWstr = String::ToWide(pRenderable.get()); - pRendWstr = PathReplacer::ReplaceKey(pRendWstr); - - rend_data = Json::LoadParseJson(pRendWstr); - if (!rend_data.is_object()) return false; - } - else if (pRenderable.is_object()) - { - rend_data = pRenderable; - } - else + nlohmann::json mObjectFile = Json::LoadParseJson(path); + if (!mObjectFile.is_object()) { - return false; + DebugErrorL("Couldn't load object database: ", path); + return; } - return Mod::LoadRenderable(rend_data, tex_data, mesh_path); - } - - glm::vec3 Mod::LoadPartCollision(const nlohmann::json& collision) - { - const bool isBoxCol = collision.contains("box"); - const bool isHullCol = collision.contains("hull"); - if (isBoxCol || isHullCol) + for (const auto& l_cur_item : mObjectFile.items()) { - const auto& b_Col = collision.at(isBoxCol ? "box" : "hull"); + if (!l_cur_item.value().is_array()) continue; - if (b_Col.is_object()) + const std::string l_key_str = l_cur_item.key(); + if (m_DataLoaders.find(l_key_str) != m_DataLoaders.end()) { - const auto& xPos = Json::Get(b_Col, "x"); - const auto& yPos = Json::Get(b_Col, "y"); - const auto& zPos = Json::Get(b_Col, "z"); - - if (xPos.is_number() && yPos.is_number() && zPos.is_number()) - return { xPos.get(), yPos.get(), zPos.get() }; - } - } - else - { - const auto& cyl_col = Json::Get(collision, "cylinder"); - if (cyl_col.is_object()) - { - const auto& c_Diameter = Json::Get(cyl_col, "diameter"); - const auto& c_Depth = Json::Get(cyl_col, "depth"); - - if (c_Diameter.is_number() && c_Depth.is_number()) - { - const float f_Diameter = c_Diameter.get(); - const float f_Depth = c_Depth.get(); - - const auto& c_Axis = Json::Get(cyl_col, "axis"); - const std::string c_AxisStr = (c_Axis.is_string() ? c_Axis.get() : "z"); - - switch (c_AxisStr[0]) - { - case 'x': case 'X': - return { f_Depth, f_Diameter, f_Diameter }; - case 'y': case 'Y': - return { f_Diameter, f_Depth, f_Diameter }; - case 'z': case 'Z': - return { f_Diameter, f_Diameter, f_Depth }; - } - } + m_DataLoaders.at(l_key_str)(l_cur_item.value(), this); } else { - const auto& sphere_col = Json::Get(collision, "sphere"); - if (sphere_col.is_object()) - { - const auto& s_Diameter = Json::Get(sphere_col, "diameter"); - if (s_Diameter.is_number()) - return glm::vec3(s_Diameter.get()); - } + DebugErrorL("Couldn't find the loader for \"", l_key_str, "\""); } } - - return glm::vec3(1.0f); - } - - void Mod::LoadParts(const nlohmann::json& fJson) - { - const auto& pList = Json::Get(fJson, "partList"); - if (!pList.is_array()) return; - - ConvData::ProgressMax += pList.size(); - for (const auto& lPart : pList) - { - const auto& pUuid = Json::Get(lPart, "uuid"); - const auto& pColor = Json::Get(lPart, "color"); - const auto& pRenderable = Json::Get(lPart, "renderable"); - - if (!pUuid.is_string()) continue; - - SMBC::Uuid uuid_obj(pUuid.get()); - - if (AllObjects.find(uuid_obj) != AllObjects.end()) - { - DebugWarningL("An object with this uuid already exists! (", uuid_obj.ToString(), ")"); - continue; - } - - std::wstring mesh_path; - Texture::Texture tex_data; - if (!Mod::GetRenderableData(lPart, tex_data, mesh_path)) - continue; - - const std::wstring l_NameWstr = m_LanguageDb.GetTranslation(uuid_obj); - const glm::vec3 pBounds = Mod::LoadPartCollision(lPart); - - PartData* new_part = new PartData(uuid_obj, mesh_path, l_NameWstr, tex_data, pBounds); - new_part->ModPtr = this; - - const auto new_pair = std::make_pair(new_part->Uuid, new_part); - Mod::AllObjects.insert(new_pair); - m_Objects.insert(new_pair); - - ConvData::ProgressValue++; - } - } - - void Mod::LoadObjectFile(const std::wstring& path) - { - nlohmann::json mObjectFile = Json::LoadParseJson(path); - if (!mObjectFile.is_object()) - { - DebugErrorL("Couldn't load object database: ", path); - return; - } - - this->LoadBlocks(mObjectFile); - this->LoadParts(mObjectFile); } bool Mod::IsShapeSetExtensionValid(const std::string& extension) @@ -355,8 +73,9 @@ namespace SMBC if (!mCurDir.is_regular_file()) continue; const fs::path& fPath = mCurDir.path(); + if (!fPath.has_filename() || !fPath.has_extension()) continue; - if (fPath.has_filename() && fPath.has_extension() && this->IsShapeSetExtensionValid(fPath.extension().string())) + if (this->IsShapeSetExtensionValid(fPath.extension().string())) this->LoadObjectFile(fPath.wstring()); } } @@ -368,7 +87,7 @@ namespace SMBC m_LanguageDb.LoadLanguageFile(path); } - static std::wstring g_ShapeSetExtensions[2] = + static const std::wstring g_ShapeSetExtensions[2] = { L".shapedb", L".json" diff --git a/Code/ObjectDatabase/ModData.h b/Code/ObjectDatabase/ModData.h index f377f55..ecbd6b9 100644 --- a/Code/ObjectDatabase/ModData.h +++ b/Code/ObjectDatabase/ModData.h @@ -15,6 +15,9 @@ namespace SMBC { class Mod { + friend class BlockListLoader; + friend class PartListLoader; + inline static std::unordered_map AllObjects = {}; inline static std::unordered_map Mods = {}; inline static std::vector ModsArray = {}; @@ -29,23 +32,9 @@ namespace SMBC Uuid m_Uuid; private: - static void GetBlockMaterials(const nlohmann::json& block, Texture::TextureList& tex); - static bool GetBlockTextures(const nlohmann::json& block, Texture::TextureList& tex); - void LoadBlocks(const nlohmann::json& fJson); - - static void LoadTextureList(const nlohmann::json& texList, Texture::TextureList& entry); - static void AddSubMesh(const nlohmann::json& subMesh, Texture::Texture& tex, const std::wstring& idx); - static bool TryLoadSubMeshList(const nlohmann::json& pLodItem, Texture::Texture& tex); - static bool TryLoadSubMeshMap (const nlohmann::json& pLodItem, Texture::Texture& tex); - static bool LoadSubMeshes(const nlohmann::json& pLodItem, Texture::Texture& tex); - static bool LoadRenderable(const nlohmann::json& pRenderable, Texture::Texture& tex_data, std::wstring& mesh_path); - static bool GetRenderableData(const nlohmann::json& part, Texture::Texture& tex_data, std::wstring& mesh_path); - static glm::vec3 LoadPartCollision(const nlohmann::json& collision); - void LoadParts(const nlohmann::json& fJson); - void LoadObjectFile(const std::wstring& path); - bool IsShapeSetExtensionValid(const std::string& extension); + public: void LoadObjectsFromDirectory(const std::wstring& dir); void LoadTranslations(const std::wstring& path); diff --git a/Code/ObjectDatabase/ObjectData.cpp b/Code/ObjectDatabase/ObjectData.cpp index 14358b8..aa9a245 100644 --- a/Code/ObjectDatabase/ObjectData.cpp +++ b/Code/ObjectDatabase/ObjectData.cpp @@ -11,12 +11,14 @@ namespace SMBC const SMBC::Uuid& uuid, const std::wstring& name, SMBC::Texture::TextureList& textures, - const int& tiling) + const int& tiling, + Mod* pMod) { this->Uuid = uuid; this->Name = name; this->Tiling = tiling; this->TextureList = textures; + this->ModPtr = pMod; } ObjectType PartData::Type() const @@ -29,12 +31,14 @@ namespace SMBC const std::wstring& path, const std::wstring& name, SMBC::Texture::Texture& textures, - const glm::vec3& bounds) + const glm::vec3& bounds, + Mod* pMod) { this->Uuid = uuid; this->Path = path; this->Name = name; this->TextureList = textures; this->Bounds = bounds; + this->ModPtr = pMod; } } \ No newline at end of file diff --git a/Code/ObjectDatabase/ObjectData.h b/Code/ObjectDatabase/ObjectData.h index 7b65d65..f99fa25 100644 --- a/Code/ObjectDatabase/ObjectData.h +++ b/Code/ObjectDatabase/ObjectData.h @@ -42,7 +42,8 @@ namespace SMBC const SMBC::Uuid& uuid, const std::wstring& name, SMBC::Texture::TextureList& textures, - const int& tiling + const int& tiling, + Mod* pMod ); ~BlockData() = default; }; @@ -61,7 +62,8 @@ namespace SMBC const std::wstring& path, const std::wstring& name, SMBC::Texture::Texture& textures, - const glm::vec3& bounds + const glm::vec3& bounds, + Mod* pMod ); ~PartData() = default; };