From 4d7774f19ec9bf0a31d4358f661e7044a99199c9 Mon Sep 17 00:00:00 2001 From: parax0 Date: Mon, 10 Aug 2015 21:42:50 -0400 Subject: [PATCH] Added interface for importing models in the Model Editor + fixed bugs --- PrimeWorldEditor.pro | 6 +- Resource/CMaterialPass.cpp | 2 +- Resource/factory/CMaterialLoader.cpp | 8 ++- Resource/factory/CModelLoader.cpp | 10 +++ UI/CModelEditorWindow.cpp | 99 +++++++++++++++++++++++----- UI/CModelEditorWindow.h | 5 ++ UI/CModelEditorWindow.ui | 30 ++++++--- 7 files changed, 130 insertions(+), 30 deletions(-) diff --git a/PrimeWorldEditor.pro b/PrimeWorldEditor.pro index 9726f2df..0236052e 100644 --- a/PrimeWorldEditor.pro +++ b/PrimeWorldEditor.pro @@ -133,7 +133,8 @@ SOURCES += \ UI/WStringPreviewPanel.cpp \ UI/WScanPreviewPanel.cpp \ UI/WIntegralSpinBox.cpp \ - UI/CAboutDialog.cpp + UI/CAboutDialog.cpp \ + UI/CGizmo.cpp HEADERS += \ Common/AnimUtil.h \ @@ -280,7 +281,8 @@ HEADERS += \ UI/WStringPreviewPanel.h \ UI/WScanPreviewPanel.h \ UI/WIntegralSpinBox.h \ - UI/CAboutDialog.h + UI/CAboutDialog.h \ + UI/CGizmo.h FORMS += \ UI/CWorldEditorWindow.ui \ diff --git a/Resource/CMaterialPass.cpp b/Resource/CMaterialPass.cpp index b83befe5..ec81dd65 100644 --- a/Resource/CMaterialPass.cpp +++ b/Resource/CMaterialPass.cpp @@ -15,7 +15,7 @@ CMaterialPass::CMaterialPass(CMaterial *pParent) mKColorSel = eKonstOne; mKAlphaSel = eKonstOne; mRasSel = eRasColorNull; - mTexCoordSource = 0; + mTexCoordSource = 0xFF; mAnimMode = eNoUVAnim; for (u32 iParam = 0; iParam < 4; iParam++) diff --git a/Resource/factory/CMaterialLoader.cpp b/Resource/factory/CMaterialLoader.cpp index 3dbc6ff8..54d63b37 100644 --- a/Resource/factory/CMaterialLoader.cpp +++ b/Resource/factory/CMaterialLoader.cpp @@ -39,7 +39,7 @@ void CMaterialLoader::ReadPrimeMatSet() { mpSet->mMaterials[iMat] = ReadPrimeMaterial(); mpSet->mMaterials[iMat]->mVersion = mVersion; - mpSet->mMaterials[iMat]->mName = std::string("Material #") + std::to_string(iMat); + mpSet->mMaterials[iMat]->mName = std::string("Material #") + std::to_string(iMat + 1); mpFile->Seek(matsStart + offsets[iMat], SEEK_SET); } } @@ -240,7 +240,7 @@ void CMaterialLoader::ReadCorruptionMatSet() u32 Next = mpFile->Tell() + Size; mpSet->mMaterials[iMat] = ReadCorruptionMaterial(); mpSet->mMaterials[iMat]->mVersion = mVersion; - mpSet->mMaterials[iMat]->mName = std::string("Material #") + std::to_string(iMat); + mpSet->mMaterials[iMat]->mName = std::string("Material #") + std::to_string(iMat + 1); mpFile->Seek(Next, SEEK_SET); } } @@ -581,6 +581,10 @@ CMaterial* CMaterialLoader::LoadAssimpMaterial(const aiMaterial *pAiMat) // todo: generate new material using import values. CMaterial *pMat = new CMaterial(mVersion, eNoAttributes); + aiString name; + pAiMat->Get(AI_MATKEY_NAME, name); + pMat->SetName(name.C_Str()); + // Create generic custom pass that uses Konst color CMaterialPass *pPass = new CMaterialPass(pMat); pPass->SetColorInputs(eZeroRGB, eRasRGB, eKonstRGB, eZeroRGB); diff --git a/Resource/factory/CModelLoader.cpp b/Resource/factory/CModelLoader.cpp index de61ef10..19ae0643 100644 --- a/Resource/factory/CModelLoader.cpp +++ b/Resource/factory/CModelLoader.cpp @@ -288,6 +288,14 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pMesh, CMaterialSet *pSet) desc |= (eTex0 << (iUV * 2)); pMat->SetVertexDescription(desc); + + // TEMP - disable dynamic lighting on geometry with no normals + if (!pMesh->HasNormals()) + { + pMat->SetLightingEnabled(false); + pMat->Pass(0)->SetColorInputs(eZeroRGB, eOneRGB, eKonstRGB, eZeroRGB); + pMat->Pass(0)->SetRasSel(eRasColorNull); + } } // Create surface @@ -466,6 +474,8 @@ CModel* CModelLoader::LoadCMDL(CInputStream& CMDL) { SSurface *pSurf = Loader.LoadSurface(CMDL); pModel->mSurfaces.push_back(pSurf); + pModel->mVertexCount += pSurf->VertexCount; + pModel->mTriangleCount += pSurf->TriangleCount; } pModel->mAABox = AABox; diff --git a/UI/CModelEditorWindow.cpp b/UI/CModelEditorWindow.cpp index 70558cef..283c5c4e 100644 --- a/UI/CModelEditorWindow.cpp +++ b/UI/CModelEditorWindow.cpp @@ -9,12 +9,16 @@ #include #include #include +#include +#include #include #include #include "WColorPicker.h" #include -#include +#include +#include +#include CModelEditorWindow::CModelEditorWindow(QWidget *parent) : QMainWindow(parent), @@ -145,14 +149,18 @@ void CModelEditorWindow::SetActiveModel(CModel *pModel) mpCurrentModel = pModel; mModelToken = CToken(pModel); - ui->MeshInfoLabel->setText(QString::number(pModel->GetVertexCount()) + " vertices, " + QString::number(pModel->GetTriangleCount()) + " triangles"); - ui->MatInfoLabel->setText(QString::number(pModel->GetMatCount()) + " materials, " + QString::number(pModel->GetMatSetCount()) + " set" + (pModel->GetMatSetCount() == 1 ? "" : "s")); + u32 numVertices = (pModel ? pModel->GetVertexCount() : 0); + u32 numTriangles = (pModel ? pModel->GetTriangleCount() : 0); + u32 numMats = (pModel ? pModel->GetMatCount() : 0); + u32 numMatSets = (pModel ? pModel->GetMatSetCount() : 0); + ui->MeshInfoLabel->setText(QString::number(numVertices) + " vertices, " + QString::number(numTriangles) + " triangles"); + ui->MatInfoLabel->setText(QString::number(numMats) + " materials, " + QString::number(numMatSets) + " set" + (numMatSets == 1 ? "" : "s")); // Set items in matset combo box ui->SetSelectionComboBox->blockSignals(true); ui->SetSelectionComboBox->clear(); - for (u32 iSet = 0; iSet < pModel->GetMatSetCount(); iSet++) + for (u32 iSet = 0; iSet < numMatSets; iSet++) ui->SetSelectionComboBox->addItem("Set #" + QString::number(iSet + 1)); ui->SetSelectionComboBox->setCurrentIndex(0); @@ -162,19 +170,22 @@ void CModelEditorWindow::SetActiveModel(CModel *pModel) ui->MatSelectionComboBox->blockSignals(true); ui->MatSelectionComboBox->clear(); - for (u32 iMat = 0; iMat < pModel->GetMatCount(); iMat++) - ui->MatSelectionComboBox->addItem("Material #" + QString::number(iMat + 1)); + for (u32 iMat = 0; iMat < numMats; iMat++) + { + std::string matName = pModel->GetMaterialByIndex(0, iMat)->Name(); + ui->MatSelectionComboBox->addItem(QString::fromStdString(matName)); + } ui->MatSelectionComboBox->setCurrentIndex(0); - ui->MatSelectionComboBox->setEnabled( pModel->GetMatCount() > 1 ); + ui->MatSelectionComboBox->setEnabled( numMats > 1 ); ui->MatSelectionComboBox->blockSignals(false); // Emit signals to set up UI ui->SetSelectionComboBox->currentIndexChanged(0); // Gray out set selection for models with one set - ui->SetSelectionComboBox->setEnabled( pModel->GetMatSetCount() > 1 ); - ui->MatSelectionComboBox->setEnabled( pModel->GetMatCount() > 1 ); + ui->SetSelectionComboBox->setEnabled( numMatSets > 1 ); + ui->MatSelectionComboBox->setEnabled( numMats > 1 ); } void CModelEditorWindow::SetActiveMaterial(int MatIndex) @@ -284,7 +295,7 @@ void CModelEditorWindow::SetActivePass(int PassIndex) u32 TexCoordSrc = mpCurrentPass->TexCoordSource(); if (KColor >= 0xC) KColor -= 4; if (KAlpha >= 0x10) KAlpha -= 8; - if (Ras == 0xFF) Ras = 10; + if (Ras == 0xFF) Ras = 7; if (TexCoordSrc == 0xFF) TexCoordSrc = 0; else TexCoordSrc++; if (TexCoordSrc >= 5) TexCoordSrc -= 2; @@ -746,14 +757,15 @@ void CModelEditorWindow::on_actionConvert_to_DDS_triggered() void CModelEditorWindow::on_actionOpen_triggered() { - QString ModelFilename = QFileDialog::getOpenFileName(this, "Retro Model (*.CMDL)", "", "*.CMDL"); + QString ModelFilename = QFileDialog::getOpenFileName(this, "Save model", "", "Retro Model (*.CMDL)"); if (ModelFilename.isEmpty()) return; - CModel *Model = (CModel*) gResCache.GetResource(ModelFilename.toStdString()); - if (Model) + CModel *pModel = (CModel*) gResCache.GetResource(ModelFilename.toStdString()); + if (pModel) { - SetActiveModel(Model); - setWindowTitle("Prime World Editor - Model Editor: " + QString::fromStdString(Model->Source())); + SetActiveModel(pModel); + setWindowTitle("Prime World Editor - Model Editor: " + QString::fromStdString(pModel->Source())); + mOutputFilename = QString::fromStdString(pModel->FullSource()); } gResCache.Clean(); @@ -763,7 +775,13 @@ void CModelEditorWindow::on_actionSave_triggered() { if (!mpCurrentModel) return; - CFileOutStream CMDLOut(mpCurrentModel->Source(), IOUtil::BigEndian); + if (mOutputFilename.isEmpty()) + { + on_actionSave_as_triggered(); + return; + } + + CFileOutStream CMDLOut(mOutputFilename.toStdString(), IOUtil::BigEndian); CModelCooker::WriteCookedModel(mpCurrentModel, ePrime, CMDLOut); QMessageBox::information(this, "Saved", "Model saved!"); } @@ -793,3 +811,52 @@ void CModelEditorWindow::on_ClearColorPicker_colorChanged(const QColor &Color) CColor NewColor((u8) Color.red(), (u8) Color.green(), (u8) Color.blue(), 255); mpRenderer->SetClearColor(NewColor); } + +void CModelEditorWindow::on_actionImport_triggered() +{ + QString filename = QFileDialog::getOpenFileName(this, "Model", "", "*.obj;*.fbx;*.dae;*.3ds;*.blend"); + if (filename.isEmpty()) return; + + Assimp::Importer importer; + importer.SetPropertyInteger(AI_CONFIG_PP_FD_REMOVE, 1); + importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, + aiComponent_TANGENTS_AND_BITANGENTS | + aiComponent_ANIMATIONS | + aiComponent_LIGHTS | + aiComponent_CAMERAS); + + const aiScene *pScene = importer.ReadFile(filename.toStdString(), + aiProcess_JoinIdenticalVertices | + aiProcess_Triangulate | + aiProcess_RemoveComponent | + //aiProcess_GenSmoothNormals | + //aiProcess_SplitLargeMeshes | + //aiProcess_PreTransformVertices | + aiProcess_SortByPType | + //aiProcess_FindDegenerates | + //aiProcess_FindInvalidData | + //aiProcess_GenUVCoords | + aiProcess_RemoveRedundantMaterials | + aiProcess_OptimizeGraph); + + CModel *pModel = nullptr; + CMaterialSet *pSet = CMaterialLoader::ImportAssimpMaterials(pScene, ePrime); + pModel = CModelLoader::ImportAssimpNode(pScene->mRootNode, pScene, *pSet); + + SetActiveModel(pModel); + setWindowTitle("Prime World Editor - Model Editor: Untitled"); + mOutputFilename = ""; + gResCache.Clean(); +} + +void CModelEditorWindow::on_actionSave_as_triggered() +{ + QString filename = QFileDialog::getSaveFileName(this, "Save model", "", "Retro Model (*.CMDL)"); + if (filename.isEmpty()) return; + + mOutputFilename = filename; + on_actionSave_triggered(); + + std::string name = StringUtil::GetFileNameWithExtension(filename.toStdString()); + setWindowTitle("Prime World Editor - Model Editor: " + QString::fromStdString(name)); +} diff --git a/UI/CModelEditorWindow.h b/UI/CModelEditorWindow.h index e460b569..132c9b79 100644 --- a/UI/CModelEditorWindow.h +++ b/UI/CModelEditorWindow.h @@ -25,6 +25,7 @@ class CModelEditorWindow : public QMainWindow Ui::CModelEditorWindow *ui; CRenderer *mpRenderer; CSceneManager *mpScene; + QString mOutputFilename; CModel *mpCurrentModel; CToken mModelToken; CModelNode *mpCurrentModelNode; @@ -115,6 +116,10 @@ private slots: void on_ClearColorPicker_colorChanged(const QColor &); + void on_actionImport_triggered(); + + void on_actionSave_as_triggered(); + signals: void Closed(); }; diff --git a/UI/CModelEditorWindow.ui b/UI/CModelEditorWindow.ui index 83da12be..51e0979e 100644 --- a/UI/CModelEditorWindow.ui +++ b/UI/CModelEditorWindow.ui @@ -2407,6 +2407,8 @@ + + @@ -2466,8 +2468,27 @@ Export curent model's textures + + + Import + + + + + Save as... + + + + WColorPicker + QWidget +
WColorPicker.h
+ 1 + + colorChanged(QColor) + +
WResourceSelector QWidget @@ -2480,15 +2501,6 @@
CEditorGLWidget.h
1
- - WColorPicker - QWidget -
WColorPicker.h
- 1 - - colorChanged(QColor) - -
WDraggableSpinBox QDoubleSpinBox