From de2b6f63074ceb2c8f2b1db69969239649679c55 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Tue, 12 Apr 2022 20:18:22 -0400 Subject: [PATCH] Add export button and support for exporting all mesh parts --- mdlviewer/include/mainwindow.h | 2 +- mdlviewer/src/mainwindow.cpp | 95 +++++++++++++++++++++------------- renderer/include/renderer.hpp | 1 + renderer/src/renderer.cpp | 1 + 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/mdlviewer/include/mainwindow.h b/mdlviewer/include/mainwindow.h index 32e2427..0582527 100644 --- a/mdlviewer/include/mainwindow.h +++ b/mdlviewer/include/mainwindow.h @@ -50,7 +50,7 @@ public: void refreshModel(); - void exportModel(Model& model); + void exportModel(Model& model, QString fileName); private: std::vector gears; diff --git a/mdlviewer/src/mainwindow.cpp b/mdlviewer/src/mainwindow.cpp index a13edc7..d50594c 100644 --- a/mdlviewer/src/mainwindow.cpp +++ b/mdlviewer/src/mainwindow.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "gamedata.h" #include "exhparser.h" @@ -157,6 +159,9 @@ MainWindow::MainWindow(GameData& data) : data(data) { timer->start(1000); #endif + QHBoxLayout* controlLayout = new QHBoxLayout(); + viewportLayout->addLayout(controlLayout); + QComboBox* raceCombo = new QComboBox(); for(auto [race, raceName] : raceNames) { raceCombo->addItem(raceName.data()); @@ -167,7 +172,19 @@ MainWindow::MainWindow(GameData& data) : data(data) { refreshModel(); }); - viewportLayout->addWidget(raceCombo); + controlLayout->addWidget(raceCombo); + + QPushButton* exportButton = new QPushButton("Export"); + + connect(exportButton, &QPushButton::clicked, [this] { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"), + "model.fbx", + tr("FBX Files (*.fbx)")); + + exportModel(vkWindow->models[0].model, fileName); + }); + + controlLayout->addWidget(exportButton); connect(listWidget, &QListWidget::itemClicked, [this](QListWidgetItem* item) { for(auto& gear : gears) { @@ -202,47 +219,55 @@ void MainWindow::refreshModel() { } } -void MainWindow::exportModel(Model& model) { +void MainWindow::exportModel(Model& model, QString fileName) { Assimp::Exporter exporter; aiScene scene; scene.mRootNode = new aiNode(); + scene.mRootNode->mNumChildren = model.lods[0].parts.size(); + scene.mRootNode->mChildren = new aiNode*[scene.mRootNode->mNumChildren]; + + scene.mNumMeshes = model.lods[0].parts.size(); + scene.mMeshes = new aiMesh*[scene.mNumMeshes]; + + for(int i = 0; i < model.lods[0].parts.size(); i++) { + scene.mMeshes[i] = new aiMesh(); + scene.mMeshes[i]->mMaterialIndex = 0; + + auto& node = scene.mRootNode->mChildren[i]; + node = new aiNode(); + node->mNumMeshes = 1; + node->mMeshes = new unsigned int [scene.mRootNode->mNumMeshes]; + node->mMeshes[0] = i; + + auto mesh = scene.mMeshes[i]; + mesh->mNumVertices = model.lods[0].parts[i].vertices.size(); + mesh->mVertices = new aiVector3D [mesh->mNumVertices]; + for(int j = 0; j < mesh->mNumVertices; j++) { + auto vertex = model.lods[0].parts[i].vertices[j]; + mesh->mVertices[j] = aiVector3D(vertex.position[0], vertex.position[1], vertex.position[2]); + } + + mesh->mNumFaces = model.lods[0].parts[i].indices.size() / 3; + mesh->mFaces = new aiFace[mesh->mNumFaces]; + + int lastFace = 0; + for(int j = 0; j < model.lods[0].parts[i].indices.size(); j += 3) { + aiFace& face = mesh->mFaces[lastFace++]; + + face.mNumIndices = 3; + face.mIndices = new unsigned int[face.mNumIndices]; + + face.mIndices[0] = model.lods[0].parts[i].indices[j]; + face.mIndices[1] = model.lods[0].parts[i].indices[j + 1]; + face.mIndices[2] = model.lods[0].parts[i].indices[j + 2]; + } + } + scene.mNumMaterials = 1; scene.mMaterials = new aiMaterial*[1]; scene.mMaterials[0] = new aiMaterial(); - scene.mNumMeshes = 1; - scene.mMeshes = new aiMesh*[scene.mNumMeshes]; - scene.mMeshes[0] = new aiMesh(); - scene.mMeshes[0]->mMaterialIndex = 0; - - scene.mRootNode->mNumMeshes = 1; - scene.mRootNode->mMeshes = new unsigned int [scene.mRootNode->mNumMeshes]; - scene.mRootNode->mMeshes[0] = 0; - - auto mesh = scene.mMeshes[0]; - mesh->mNumVertices = model.lods[0].parts[0].vertices.size(); - mesh->mVertices = new aiVector3D [mesh->mNumVertices]; - for(int i = 0; i < mesh->mNumVertices; i++) { - auto vertex = model.lods[0].parts[0].vertices[i]; - mesh->mVertices[i] = aiVector3D(vertex.position[0], vertex.position[1], vertex.position[2]); - } - - mesh->mNumFaces = model.lods[0].parts[0].indices.size() / 3; - mesh->mFaces = new aiFace[mesh->mNumFaces]; - - int lastFace = 0; - for(int i = 0; i < model.lods[0].parts[0].indices.size(); i += 3) { - aiFace& face = mesh->mFaces[lastFace++]; - - face.mNumIndices = 3; - face.mIndices = new unsigned int[face.mNumIndices]; - - face.mIndices[0] = model.lods[0].parts[0].indices[i]; - face.mIndices[1] = model.lods[0].parts[0].indices[i + 1]; - face.mIndices[2] = model.lods[0].parts[0].indices[i + 2]; - } - - exporter.Export(&scene, "fbx", "test.fbx"); + exporter.Export(&scene, "fbx", fileName.toStdString()); } diff --git a/renderer/include/renderer.hpp b/renderer/include/renderer.hpp index 31b3076..3b55d59 100644 --- a/renderer/include/renderer.hpp +++ b/renderer/include/renderer.hpp @@ -14,6 +14,7 @@ struct RenderPart { }; struct RenderModel { + Model model; std::vector parts; }; diff --git a/renderer/src/renderer.cpp b/renderer/src/renderer.cpp index fd466ec..b3b8ae6 100644 --- a/renderer/src/renderer.cpp +++ b/renderer/src/renderer.cpp @@ -510,6 +510,7 @@ uint32_t Renderer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags pro RenderModel Renderer::addModel(const Model& model) { RenderModel renderModel; + renderModel.model = model; for(auto part : model.lods[0].parts) { RenderPart renderPart;