From 80f1e2c1dd0d49245db3db638a3bfd7792ba35d3 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 17 May 2025 10:43:08 -0400 Subject: [PATCH] Be a little bit more efficient when loading static map objects Still not great loading times, but it's now somewhat bearable on debug builds. It now doesn't try to load duplicate models at all. Most of the time is actually spent inside of Physis parsing the model, which I'll have to tackle there. --- apps/mapeditor/src/mapview.cpp | 54 +++++++++++++++++++--------------- parts/mdl/mdlpart.cpp | 14 ++++++++- parts/mdl/mdlpart.h | 6 +++- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/apps/mapeditor/src/mapview.cpp b/apps/mapeditor/src/mapview.cpp index 2326be8..e1ce2ae 100644 --- a/apps/mapeditor/src/mapview.cpp +++ b/apps/mapeditor/src/mapview.cpp @@ -58,34 +58,40 @@ MapView::MapView(GameData *data, FileCache &cache, AppState *appState, QWidget * case physis_LayerEntry::Tag::BG: { std::string assetPath = object.data.bg._0.asset_path; if (!assetPath.empty()) { - auto plateMdlFile = physis_gamedata_extract_file(m_data, assetPath.c_str()); - if (plateMdlFile.size == 0) { - continue; - } - - auto plateMdl = physis_mdl_parse(plateMdlFile); - if (plateMdl.p_ptr != nullptr) { - std::vector materials; - for (uint32_t j = 0; j < plateMdl.num_material_names; j++) { - const char *material_name = plateMdl.material_names[j]; - - auto mat = physis_material_parse(m_cache.lookupFile(QLatin1String(material_name))); - materials.push_back(mat); + if (!mdlPart->modelExists(QString::fromStdString(assetPath))) { + auto plateMdlFile = physis_gamedata_extract_file(m_data, assetPath.c_str()); + if (plateMdlFile.size == 0) { + continue; } - mdlPart->addModel( - plateMdl, - false, - glm::vec3(object.transform.translation[0], object.transform.translation[1], object.transform.translation[2]), + auto plateMdl = physis_mdl_parse(plateMdlFile); + if (plateMdl.p_ptr != nullptr) { + std::vector materials; + for (uint32_t j = 0; j < plateMdl.num_material_names; j++) { + const char *material_name = plateMdl.material_names[j]; + + auto mat = physis_material_parse(m_cache.lookupFile(QLatin1String(material_name))); + materials.push_back(mat); + } + + mdlPart->addModel( + plateMdl, + false, + glm::vec3(object.transform.translation[0], object.transform.translation[1], object.transform.translation[2]), + QString::fromStdString(assetPath), + materials, + 0); + + // We don't need this, and it will just take up memory + physis_mdl_free(&plateMdl); + } + + physis_free_file(&plateMdlFile); + } else { + mdlPart->addExistingModel( QString::fromStdString(assetPath), - materials, - 0); - - // We don't need this, and it will just take up memory - physis_mdl_free(&plateMdl); + glm::vec3(object.transform.translation[0], object.transform.translation[1], object.transform.translation[2])); } - - physis_free_file(&plateMdlFile); } } break; } diff --git a/parts/mdl/mdlpart.cpp b/parts/mdl/mdlpart.cpp index 1dc2e78..94adce6 100644 --- a/parts/mdl/mdlpart.cpp +++ b/parts/mdl/mdlpart.cpp @@ -82,7 +82,7 @@ void MDLPart::addModel(physis_MDL mdl, uint16_t fromBodyId, uint16_t toBodyId) { - DrawObject *model; + DrawObject *model = nullptr; if (vkWindow->sourceModels.contains(name)) { model = vkWindow->sourceModels[name]; } else { @@ -102,6 +102,7 @@ void MDLPart::addModel(physis_MDL mdl, vkWindow->sourceModels[name] = model; } + Q_ASSERT(model != nullptr); vkWindow->models.push_back(DrawObjectInstance{name, model, position}); Q_EMIT modelChanged(); @@ -432,4 +433,15 @@ RenderManager *MDLPart::manager() const return renderer; } +bool MDLPart::modelExists(const QString &name) +{ + return vkWindow->sourceModels.contains(name); +} + +void MDLPart::addExistingModel(const QString &name, glm::vec3 position) +{ + auto model = vkWindow->sourceModels[name]; + vkWindow->models.push_back(DrawObjectInstance{name, model, position}); +} + #include "moc_mdlpart.cpp" diff --git a/parts/mdl/mdlpart.h b/parts/mdl/mdlpart.h index 81fd836..dd83905 100644 --- a/parts/mdl/mdlpart.h +++ b/parts/mdl/mdlpart.h @@ -65,7 +65,9 @@ public Q_SLOTS: /// Clears all stored MDLs. void clear(); - /// Adds a new MDL with a list of materials used. + // TODO: all of this API is terrible and should be redone + bool modelExists(const QString &name); + void addModel(physis_MDL mdl, bool skinned, glm::vec3 position, @@ -75,6 +77,8 @@ public Q_SLOTS: uint16_t fromBodyId = 101, uint16_t toBodyId = 101); + void addExistingModel(const QString &name, glm::vec3 position); + void removeModel(const physis_MDL &mdl); /// Sets the skeleton any skinned MDLs should bind to.