mirror of
https://github.com/redstrate/Novus.git
synced 2025-04-27 22:27:46 +00:00
Overhaul race and lod combos in mdlviewer
The number of lods are now properly loaded from the model data, and race is checked by checking for the existence of race-specific models (I think this is the current best way?). Also, magic_enum is added as a dependency for some enum magic involving enumerating Race.
This commit is contained in:
parent
d454dcf005
commit
275c1a9976
8 changed files with 1212 additions and 41 deletions
|
@ -10,6 +10,8 @@ add_subdirectory(libxiv)
|
|||
|
||||
include(FetchContent)
|
||||
|
||||
add_subdirectory(extern/magic_enum)
|
||||
|
||||
find_package(fmt QUIET)
|
||||
|
||||
if(TARGET fmt::fmt)
|
||||
|
|
2
extern/magic_enum/CMakeLists.txt
vendored
Normal file
2
extern/magic_enum/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
add_library(magic_enum INTERFACE)
|
||||
target_include_directories(magic_enum INTERFACE include)
|
1139
extern/magic_enum/include/magic_enum.hpp
vendored
Normal file
1139
extern/magic_enum/include/magic_enum.hpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
libxiv
2
libxiv
|
@ -1 +1 @@
|
|||
Subproject commit c78a1ab2458d18ddd92fc2728e3eedd95fdc4078
|
||||
Subproject commit 872bef51bb32792750a7b2a392385fb41158ead6
|
|
@ -12,7 +12,8 @@ target_link_libraries(mdlviewer PUBLIC
|
|||
Qt5::Core
|
||||
Qt5::Widgets
|
||||
renderer
|
||||
assimp::assimp)
|
||||
assimp::assimp
|
||||
magic_enum)
|
||||
|
||||
install(TARGETS mdlviewer
|
||||
DESTINATION "${INSTALL_BIN_PATH}")
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QMainWindow>
|
||||
#include <unordered_map>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "renderer.hpp"
|
||||
#include "types/slot.h"
|
||||
|
@ -25,13 +26,24 @@ class MainWindow : public QMainWindow {
|
|||
public:
|
||||
MainWindow(GameData& data);
|
||||
|
||||
void refreshModel();
|
||||
|
||||
void exportModel(Model& model, QString fileName);
|
||||
|
||||
private:
|
||||
void loadInitialGearInfo(GearInfo& info);
|
||||
void reloadGearModel();
|
||||
void reloadGearAppearance();
|
||||
|
||||
std::vector<GearInfo> gears;
|
||||
std::vector<GearInfo*> loadedGears;
|
||||
|
||||
struct LoadedGear {
|
||||
GearInfo* gearInfo;
|
||||
Model model;
|
||||
RenderModel renderModel;
|
||||
};
|
||||
|
||||
LoadedGear loadedGear;
|
||||
|
||||
QComboBox* raceCombo, *lodCombo;
|
||||
|
||||
Race currentRace = Race::HyurMidlanderMale;
|
||||
int currentLod = 0;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <assimp/postprocess.h>
|
||||
#include <QPushButton>
|
||||
#include <QFileDialog>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "gamedata.h"
|
||||
#include "exhparser.h"
|
||||
|
@ -163,29 +164,20 @@ MainWindow::MainWindow(GameData& data) : data(data) {
|
|||
QHBoxLayout* controlLayout = new QHBoxLayout();
|
||||
viewportLayout->addLayout(controlLayout);
|
||||
|
||||
QComboBox* raceCombo = new QComboBox();
|
||||
raceCombo->addItem("Midlander Male");
|
||||
raceCombo->addItem("Midlander Female");
|
||||
|
||||
/*for(auto [race, raceName] : raceNames) {
|
||||
raceCombo->addItem(raceName.data());
|
||||
}*/
|
||||
raceCombo = new QComboBox();
|
||||
|
||||
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
currentRace = (Race)index;
|
||||
refreshModel();
|
||||
reloadGearModel();
|
||||
});
|
||||
|
||||
controlLayout->addWidget(raceCombo);
|
||||
|
||||
auto lodCombo = new QComboBox();
|
||||
lodCombo->addItem("0");
|
||||
lodCombo->addItem("1");
|
||||
lodCombo->addItem("2");
|
||||
lodCombo = new QComboBox();
|
||||
|
||||
connect(lodCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
currentLod = index;
|
||||
refreshModel();
|
||||
reloadGearAppearance();
|
||||
});
|
||||
|
||||
controlLayout->addWidget(lodCombo);
|
||||
|
@ -210,33 +202,14 @@ MainWindow::MainWindow(GameData& data) : data(data) {
|
|||
|
||||
connect(listWidget, &QListWidget::itemClicked, [this](QListWidgetItem* item) {
|
||||
for(auto& gear : gears) {
|
||||
if(gear.name == item->text().toStdString())
|
||||
loadedGears = {&gear};
|
||||
if(gear.name == item->text().toStdString()) {
|
||||
loadInitialGearInfo(gear);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
refreshModel();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::refreshModel() {
|
||||
#ifdef USE_STANDALONE_WINDOW
|
||||
standaloneWindow->models.clear();
|
||||
#else
|
||||
vkWindow->models.clear();
|
||||
#endif
|
||||
|
||||
for(auto gear : loadedGears) {
|
||||
auto mdl_data = data.extractFile(build_equipment_path(gear->modelInfo.primaryID, currentRace, gear->slot));
|
||||
auto model = parseMDL(*mdl_data);
|
||||
|
||||
#ifndef USE_STANDALONE_WINDOW
|
||||
vkWindow->models.push_back(renderer->addModel(model, currentLod));
|
||||
#else
|
||||
standaloneWindow->models.push_back(renderer->addModel(model, currentLod));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::exportModel(Model& model, QString fileName) {
|
||||
Assimp::Exporter exporter;
|
||||
|
||||
|
@ -289,3 +262,42 @@ void MainWindow::exportModel(Model& model, QString fileName) {
|
|||
|
||||
exporter.Export(&scene, "fbx", fileName.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::loadInitialGearInfo(GearInfo& info) {
|
||||
loadedGear.gearInfo = &info;
|
||||
|
||||
raceCombo->clear();
|
||||
for(auto [race, race_name] : magic_enum::enum_entries<Race>()) {
|
||||
if(data.exists(build_equipment_path(loadedGear.gearInfo->modelInfo.primaryID, race, loadedGear.gearInfo->slot)))
|
||||
raceCombo->addItem(race_name.data());
|
||||
}
|
||||
|
||||
currentLod = 0;
|
||||
currentRace = Race::HyurMidlanderMale;
|
||||
|
||||
reloadGearModel();
|
||||
}
|
||||
|
||||
void MainWindow::reloadGearModel() {
|
||||
auto mdl_data = data.extractFile(build_equipment_path(loadedGear.gearInfo->modelInfo.primaryID, currentRace, loadedGear.gearInfo->slot));
|
||||
if(mdl_data == std::nullopt)
|
||||
return;
|
||||
|
||||
loadedGear.model = parseMDL(*mdl_data);
|
||||
|
||||
lodCombo->clear();
|
||||
for(int i = 0; i < loadedGear.model.lods.size(); i++)
|
||||
lodCombo->addItem(QString::number(i));
|
||||
|
||||
reloadGearAppearance();
|
||||
}
|
||||
|
||||
void MainWindow::reloadGearAppearance() {
|
||||
loadedGear.renderModel = renderer->addModel(loadedGear.model, currentLod);
|
||||
|
||||
#ifndef USE_STANDALONE_WINDOW
|
||||
vkWindow->models = {loadedGear.renderModel};
|
||||
#else
|
||||
standaloneWindow->models = {loadedGear.renderModel};
|
||||
#endif
|
||||
}
|
|
@ -512,6 +512,9 @@ RenderModel Renderer::addModel(const Model& model, int lod) {
|
|||
RenderModel renderModel;
|
||||
renderModel.model = model;
|
||||
|
||||
if(lod < 0 || lod > model.lods.size())
|
||||
return {};
|
||||
|
||||
for(auto part : model.lods[lod].parts) {
|
||||
RenderPart renderPart;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue