diff --git a/armoury/include/gearview.h b/armoury/include/gearview.h index 94fa021..e24cb9d 100644 --- a/armoury/include/gearview.h +++ b/armoury/include/gearview.h @@ -53,6 +53,8 @@ public: Subrace currentSubrace = Subrace::Midlander; Gender currentGender = Gender::Male; + QString getLoadedGearPath() const; + Q_SIGNALS: void gearChanged(); void modelReloaded(); @@ -92,6 +94,7 @@ private: struct LoadedGear { GearInfo info; physis_MDL mdl; + QLatin1String path; }; std::vector loadedGears; diff --git a/armoury/include/singlegearview.h b/armoury/include/singlegearview.h index 20807c1..7f588a8 100644 --- a/armoury/include/singlegearview.h +++ b/armoury/include/singlegearview.h @@ -12,11 +12,15 @@ struct GameData; class SingleGearView : public QWidget { Q_OBJECT + public: explicit SingleGearView(GameData* data, FileCache& cache); + QString getLoadedGearPath() const; + Q_SIGNALS: void gearChanged(); + void gotMDLPath(); void raceChanged(); void subraceChanged(); @@ -49,7 +53,7 @@ private: GearView* gearView = nullptr; QComboBox *raceCombo, *subraceCombo, *genderCombo, *lodCombo; - QPushButton *addToFMVButton, *exportButton; + QPushButton *addToFMVButton, *importButton, *exportButton; bool loadingComboData = false; bool fmvAvailable = false; diff --git a/armoury/src/gearview.cpp b/armoury/src/gearview.cpp index d0a2a6c..5477f4a 100644 --- a/armoury/src/gearview.cpp +++ b/armoury/src/gearview.cpp @@ -18,6 +18,7 @@ GearView::GearView(GameData* data, FileCache& cache) : data(data), cache(cache) reloadRaceDeforms(); auto layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(mdlPart); setLayout(layout); @@ -277,17 +278,20 @@ void GearView::updatePart() if (gearDirty) { for (auto &gearAddition : queuedGearAdditions) { + QLatin1String mdlPath = QLatin1String( + physis_build_equipment_path(gearAddition.info.modelInfo.primaryID, currentRace, currentSubrace, currentGender, gearAddition.info.slot)); + qInfo() << "Looking up" << magic_enum::enum_name(currentRace) << magic_enum::enum_name(currentSubrace) << magic_enum::enum_name(currentGender); - auto mdl_data = cache.lookupFile(QLatin1String( - physis_build_equipment_path(gearAddition.info.modelInfo.primaryID, currentRace, currentSubrace, currentGender, gearAddition.info.slot))); + auto mdl_data = cache.lookupFile(mdlPath); // attempt to load the next best race // currently hardcoded to hyur midlander Race fallbackRace = currentRace; Subrace fallbackSubrace = currentSubrace; if (mdl_data.size == 0) { - mdl_data = cache.lookupFile(QLatin1String( - physis_build_equipment_path(gearAddition.info.modelInfo.primaryID, Race::Hyur, Subrace::Midlander, currentGender, gearAddition.info.slot))); + mdlPath = QLatin1String( + physis_build_equipment_path(gearAddition.info.modelInfo.primaryID, Race::Hyur, Subrace::Midlander, currentGender, gearAddition.info.slot)); + mdl_data = cache.lookupFile(mdlPath); fallbackRace = Race::Hyur; fallbackSubrace = Subrace::Midlander; } @@ -318,6 +322,7 @@ void GearView::updatePart() mdlPart->addModel(mdl, materials, currentLod); gearAddition.mdl = mdl; + gearAddition.path = mdlPath; loadedGears.push_back(gearAddition); } } @@ -429,4 +434,12 @@ bool GearView::needsUpdate() const return gearDirty || raceDirty || faceDirty || hairDirty || earDirty || tailDirty; } +QString GearView::getLoadedGearPath() const +{ + if (loadedGears.empty()) { + return {}; + } + return loadedGears[0].path; +} + #include "moc_gearview.cpp" diff --git a/armoury/src/mainwindow.cpp b/armoury/src/mainwindow.cpp index 0766058..f650568 100644 --- a/armoury/src/mainwindow.cpp +++ b/armoury/src/mainwindow.cpp @@ -83,11 +83,14 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data), cache(FileCache{*in_ connect(gearView, &SingleGearView::addToFullModelViewer, this, [=](GearInfo& info) { fullModelViewer->addGear(info); }); + + auto tabWidget = new QTabWidget(); + tabWidget->addTab(gearView, QStringLiteral("Models")); + layout->addWidget(tabWidget); + + fullModelViewer = new FullModelViewer(&data, cache); connect(fullModelViewer, &FullModelViewer::loadingChanged, this, [=](const bool loading) { gearView->setFMVAvailable(!loading); }); - layout->addWidget(gearView); - - fullModelViewer = new FullModelViewer(&data, cache); fullModelViewer->show(); } \ No newline at end of file diff --git a/armoury/src/singlegearview.cpp b/armoury/src/singlegearview.cpp index 3befd56..ecce76a 100644 --- a/armoury/src/singlegearview.cpp +++ b/armoury/src/singlegearview.cpp @@ -3,10 +3,11 @@ #include "singlegearview.h" +#include #include +#include #include #include -#include #include "filecache.h" #include "magic_enum.hpp" @@ -21,11 +22,22 @@ SingleGearView::SingleGearView(GameData* data, FileCache& cache) : data(data) { auto layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(gearView); setLayout(layout); + auto mdlPathEdit = new QLineEdit(); + mdlPathEdit->setReadOnly(true); + + connect(this, &SingleGearView::gotMDLPath, this, [this, mdlPathEdit] { + mdlPathEdit->setText(gearView->getLoadedGearPath()); + }); + + auto topControlLayout = new QHBoxLayout(); auto controlLayout = new QHBoxLayout(); + + layout->addWidget(mdlPathEdit); layout->addLayout(controlLayout); + layout->addWidget(gearView); + layout->addLayout(topControlLayout); raceCombo = new QComboBox(); connect(raceCombo, qOverload(&QComboBox::currentIndexChanged), [this](int index) { @@ -64,14 +76,19 @@ SingleGearView::SingleGearView(GameData* data, FileCache& cache) : data(data) { controlLayout->addWidget(lodCombo); addToFMVButton = new QPushButton(QStringLiteral("Add to FMV")); + addToFMVButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add-user"))); connect(addToFMVButton, &QPushButton::clicked, this, [this](bool) { if (currentGear.has_value()) { Q_EMIT addToFullModelViewer(*currentGear); } }); - controlLayout->addWidget(addToFMVButton); + + importButton = new QPushButton(QStringLiteral("Import...")); + importButton->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); + topControlLayout->addWidget(importButton); exportButton = new QPushButton(QStringLiteral("Export...")); + exportButton->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); connect(exportButton, &QPushButton::clicked, this, [this](bool) { if (currentGear.has_value()) { QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"), QStringLiteral("model.glb"), tr("glTF Binary File (*.glb)")); @@ -79,11 +96,13 @@ SingleGearView::SingleGearView(GameData* data, FileCache& cache) : data(data) { gearView->exportModel(fileName); } }); - controlLayout->addWidget(exportButton); + topControlLayout->addWidget(exportButton); + topControlLayout->addWidget(addToFMVButton); connect(gearView, &GearView::loadingChanged, this, [this](const bool loading) { if (!loading) { reloadGear(); + Q_EMIT gotMDLPath(); } }); connect(this, &SingleGearView::raceChanged, this, [=] { @@ -241,4 +260,9 @@ void SingleGearView::setFMVAvailable(const bool available) } } +QString SingleGearView::getLoadedGearPath() const +{ + return gearView->getLoadedGearPath(); +} + #include "moc_singlegearview.cpp" \ No newline at end of file