Added interface for importing models in the Model Editor + fixed bugs
This commit is contained in:
parent
2967a483d9
commit
4d7774f19e
|
@ -133,7 +133,8 @@ SOURCES += \
|
||||||
UI/WStringPreviewPanel.cpp \
|
UI/WStringPreviewPanel.cpp \
|
||||||
UI/WScanPreviewPanel.cpp \
|
UI/WScanPreviewPanel.cpp \
|
||||||
UI/WIntegralSpinBox.cpp \
|
UI/WIntegralSpinBox.cpp \
|
||||||
UI/CAboutDialog.cpp
|
UI/CAboutDialog.cpp \
|
||||||
|
UI/CGizmo.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Common/AnimUtil.h \
|
Common/AnimUtil.h \
|
||||||
|
@ -280,7 +281,8 @@ HEADERS += \
|
||||||
UI/WStringPreviewPanel.h \
|
UI/WStringPreviewPanel.h \
|
||||||
UI/WScanPreviewPanel.h \
|
UI/WScanPreviewPanel.h \
|
||||||
UI/WIntegralSpinBox.h \
|
UI/WIntegralSpinBox.h \
|
||||||
UI/CAboutDialog.h
|
UI/CAboutDialog.h \
|
||||||
|
UI/CGizmo.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
UI/CWorldEditorWindow.ui \
|
UI/CWorldEditorWindow.ui \
|
||||||
|
|
|
@ -15,7 +15,7 @@ CMaterialPass::CMaterialPass(CMaterial *pParent)
|
||||||
mKColorSel = eKonstOne;
|
mKColorSel = eKonstOne;
|
||||||
mKAlphaSel = eKonstOne;
|
mKAlphaSel = eKonstOne;
|
||||||
mRasSel = eRasColorNull;
|
mRasSel = eRasColorNull;
|
||||||
mTexCoordSource = 0;
|
mTexCoordSource = 0xFF;
|
||||||
mAnimMode = eNoUVAnim;
|
mAnimMode = eNoUVAnim;
|
||||||
|
|
||||||
for (u32 iParam = 0; iParam < 4; iParam++)
|
for (u32 iParam = 0; iParam < 4; iParam++)
|
||||||
|
|
|
@ -39,7 +39,7 @@ void CMaterialLoader::ReadPrimeMatSet()
|
||||||
{
|
{
|
||||||
mpSet->mMaterials[iMat] = ReadPrimeMaterial();
|
mpSet->mMaterials[iMat] = ReadPrimeMaterial();
|
||||||
mpSet->mMaterials[iMat]->mVersion = mVersion;
|
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);
|
mpFile->Seek(matsStart + offsets[iMat], SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ void CMaterialLoader::ReadCorruptionMatSet()
|
||||||
u32 Next = mpFile->Tell() + Size;
|
u32 Next = mpFile->Tell() + Size;
|
||||||
mpSet->mMaterials[iMat] = ReadCorruptionMaterial();
|
mpSet->mMaterials[iMat] = ReadCorruptionMaterial();
|
||||||
mpSet->mMaterials[iMat]->mVersion = mVersion;
|
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);
|
mpFile->Seek(Next, SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,6 +581,10 @@ CMaterial* CMaterialLoader::LoadAssimpMaterial(const aiMaterial *pAiMat)
|
||||||
// todo: generate new material using import values.
|
// todo: generate new material using import values.
|
||||||
CMaterial *pMat = new CMaterial(mVersion, eNoAttributes);
|
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
|
// Create generic custom pass that uses Konst color
|
||||||
CMaterialPass *pPass = new CMaterialPass(pMat);
|
CMaterialPass *pPass = new CMaterialPass(pMat);
|
||||||
pPass->SetColorInputs(eZeroRGB, eRasRGB, eKonstRGB, eZeroRGB);
|
pPass->SetColorInputs(eZeroRGB, eRasRGB, eKonstRGB, eZeroRGB);
|
||||||
|
|
|
@ -288,6 +288,14 @@ SSurface* CModelLoader::LoadAssimpMesh(const aiMesh *pMesh, CMaterialSet *pSet)
|
||||||
desc |= (eTex0 << (iUV * 2));
|
desc |= (eTex0 << (iUV * 2));
|
||||||
|
|
||||||
pMat->SetVertexDescription(desc);
|
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
|
// Create surface
|
||||||
|
@ -466,6 +474,8 @@ CModel* CModelLoader::LoadCMDL(CInputStream& CMDL)
|
||||||
{
|
{
|
||||||
SSurface *pSurf = Loader.LoadSurface(CMDL);
|
SSurface *pSurf = Loader.LoadSurface(CMDL);
|
||||||
pModel->mSurfaces.push_back(pSurf);
|
pModel->mSurfaces.push_back(pSurf);
|
||||||
|
pModel->mVertexCount += pSurf->VertexCount;
|
||||||
|
pModel->mTriangleCount += pSurf->TriangleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
pModel->mAABox = AABox;
|
pModel->mAABox = AABox;
|
||||||
|
|
|
@ -9,12 +9,16 @@
|
||||||
#include <Core/CDrawUtil.h>
|
#include <Core/CDrawUtil.h>
|
||||||
#include <Core/CRenderer.h>
|
#include <Core/CRenderer.h>
|
||||||
#include <Core/CSceneManager.h>
|
#include <Core/CSceneManager.h>
|
||||||
|
#include <Resource/factory/CModelLoader.h>
|
||||||
|
#include <Resource/factory/CMaterialLoader.h>
|
||||||
#include <Resource/factory/CTextureDecoder.h>
|
#include <Resource/factory/CTextureDecoder.h>
|
||||||
#include <Resource/cooker/CModelCooker.h>
|
#include <Resource/cooker/CModelCooker.h>
|
||||||
#include "WColorPicker.h"
|
#include "WColorPicker.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <gtc/matrix_transform.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
CModelEditorWindow::CModelEditorWindow(QWidget *parent) :
|
CModelEditorWindow::CModelEditorWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
|
@ -145,14 +149,18 @@ void CModelEditorWindow::SetActiveModel(CModel *pModel)
|
||||||
mpCurrentModel = pModel;
|
mpCurrentModel = pModel;
|
||||||
mModelToken = CToken(pModel);
|
mModelToken = CToken(pModel);
|
||||||
|
|
||||||
ui->MeshInfoLabel->setText(QString::number(pModel->GetVertexCount()) + " vertices, " + QString::number(pModel->GetTriangleCount()) + " triangles");
|
u32 numVertices = (pModel ? pModel->GetVertexCount() : 0);
|
||||||
ui->MatInfoLabel->setText(QString::number(pModel->GetMatCount()) + " materials, " + QString::number(pModel->GetMatSetCount()) + " set" + (pModel->GetMatSetCount() == 1 ? "" : "s"));
|
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
|
// Set items in matset combo box
|
||||||
ui->SetSelectionComboBox->blockSignals(true);
|
ui->SetSelectionComboBox->blockSignals(true);
|
||||||
ui->SetSelectionComboBox->clear();
|
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->addItem("Set #" + QString::number(iSet + 1));
|
||||||
|
|
||||||
ui->SetSelectionComboBox->setCurrentIndex(0);
|
ui->SetSelectionComboBox->setCurrentIndex(0);
|
||||||
|
@ -162,19 +170,22 @@ void CModelEditorWindow::SetActiveModel(CModel *pModel)
|
||||||
ui->MatSelectionComboBox->blockSignals(true);
|
ui->MatSelectionComboBox->blockSignals(true);
|
||||||
ui->MatSelectionComboBox->clear();
|
ui->MatSelectionComboBox->clear();
|
||||||
|
|
||||||
for (u32 iMat = 0; iMat < pModel->GetMatCount(); iMat++)
|
for (u32 iMat = 0; iMat < numMats; iMat++)
|
||||||
ui->MatSelectionComboBox->addItem("Material #" + QString::number(iMat + 1));
|
{
|
||||||
|
std::string matName = pModel->GetMaterialByIndex(0, iMat)->Name();
|
||||||
|
ui->MatSelectionComboBox->addItem(QString::fromStdString(matName));
|
||||||
|
}
|
||||||
|
|
||||||
ui->MatSelectionComboBox->setCurrentIndex(0);
|
ui->MatSelectionComboBox->setCurrentIndex(0);
|
||||||
ui->MatSelectionComboBox->setEnabled( pModel->GetMatCount() > 1 );
|
ui->MatSelectionComboBox->setEnabled( numMats > 1 );
|
||||||
ui->MatSelectionComboBox->blockSignals(false);
|
ui->MatSelectionComboBox->blockSignals(false);
|
||||||
|
|
||||||
// Emit signals to set up UI
|
// Emit signals to set up UI
|
||||||
ui->SetSelectionComboBox->currentIndexChanged(0);
|
ui->SetSelectionComboBox->currentIndexChanged(0);
|
||||||
|
|
||||||
// Gray out set selection for models with one set
|
// Gray out set selection for models with one set
|
||||||
ui->SetSelectionComboBox->setEnabled( pModel->GetMatSetCount() > 1 );
|
ui->SetSelectionComboBox->setEnabled( numMatSets > 1 );
|
||||||
ui->MatSelectionComboBox->setEnabled( pModel->GetMatCount() > 1 );
|
ui->MatSelectionComboBox->setEnabled( numMats > 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModelEditorWindow::SetActiveMaterial(int MatIndex)
|
void CModelEditorWindow::SetActiveMaterial(int MatIndex)
|
||||||
|
@ -284,7 +295,7 @@ void CModelEditorWindow::SetActivePass(int PassIndex)
|
||||||
u32 TexCoordSrc = mpCurrentPass->TexCoordSource();
|
u32 TexCoordSrc = mpCurrentPass->TexCoordSource();
|
||||||
if (KColor >= 0xC) KColor -= 4;
|
if (KColor >= 0xC) KColor -= 4;
|
||||||
if (KAlpha >= 0x10) KAlpha -= 8;
|
if (KAlpha >= 0x10) KAlpha -= 8;
|
||||||
if (Ras == 0xFF) Ras = 10;
|
if (Ras == 0xFF) Ras = 7;
|
||||||
if (TexCoordSrc == 0xFF) TexCoordSrc = 0;
|
if (TexCoordSrc == 0xFF) TexCoordSrc = 0;
|
||||||
else TexCoordSrc++;
|
else TexCoordSrc++;
|
||||||
if (TexCoordSrc >= 5) TexCoordSrc -= 2;
|
if (TexCoordSrc >= 5) TexCoordSrc -= 2;
|
||||||
|
@ -746,14 +757,15 @@ void CModelEditorWindow::on_actionConvert_to_DDS_triggered()
|
||||||
|
|
||||||
void CModelEditorWindow::on_actionOpen_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;
|
if (ModelFilename.isEmpty()) return;
|
||||||
|
|
||||||
CModel *Model = (CModel*) gResCache.GetResource(ModelFilename.toStdString());
|
CModel *pModel = (CModel*) gResCache.GetResource(ModelFilename.toStdString());
|
||||||
if (Model)
|
if (pModel)
|
||||||
{
|
{
|
||||||
SetActiveModel(Model);
|
SetActiveModel(pModel);
|
||||||
setWindowTitle("Prime World Editor - Model Editor: " + QString::fromStdString(Model->Source()));
|
setWindowTitle("Prime World Editor - Model Editor: " + QString::fromStdString(pModel->Source()));
|
||||||
|
mOutputFilename = QString::fromStdString(pModel->FullSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
gResCache.Clean();
|
gResCache.Clean();
|
||||||
|
@ -763,7 +775,13 @@ void CModelEditorWindow::on_actionSave_triggered()
|
||||||
{
|
{
|
||||||
if (!mpCurrentModel) return;
|
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);
|
CModelCooker::WriteCookedModel(mpCurrentModel, ePrime, CMDLOut);
|
||||||
QMessageBox::information(this, "Saved", "Model saved!");
|
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);
|
CColor NewColor((u8) Color.red(), (u8) Color.green(), (u8) Color.blue(), 255);
|
||||||
mpRenderer->SetClearColor(NewColor);
|
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));
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ class CModelEditorWindow : public QMainWindow
|
||||||
Ui::CModelEditorWindow *ui;
|
Ui::CModelEditorWindow *ui;
|
||||||
CRenderer *mpRenderer;
|
CRenderer *mpRenderer;
|
||||||
CSceneManager *mpScene;
|
CSceneManager *mpScene;
|
||||||
|
QString mOutputFilename;
|
||||||
CModel *mpCurrentModel;
|
CModel *mpCurrentModel;
|
||||||
CToken mModelToken;
|
CToken mModelToken;
|
||||||
CModelNode *mpCurrentModelNode;
|
CModelNode *mpCurrentModelNode;
|
||||||
|
@ -115,6 +116,10 @@ private slots:
|
||||||
|
|
||||||
void on_ClearColorPicker_colorChanged(const QColor &);
|
void on_ClearColorPicker_colorChanged(const QColor &);
|
||||||
|
|
||||||
|
void on_actionImport_triggered();
|
||||||
|
|
||||||
|
void on_actionSave_as_triggered();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Closed();
|
void Closed();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2407,6 +2407,8 @@
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionOpen"/>
|
<addaction name="actionOpen"/>
|
||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionSave_as"/>
|
||||||
|
<addaction name="actionImport"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExit"/>
|
<addaction name="actionExit"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -2466,8 +2468,27 @@
|
||||||
<string>Export curent model's textures</string>
|
<string>Export curent model's textures</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionImport">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave_as">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save as...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>WColorPicker</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>WColorPicker.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
<slots>
|
||||||
|
<signal>colorChanged(QColor)</signal>
|
||||||
|
</slots>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>WResourceSelector</class>
|
<class>WResourceSelector</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
|
@ -2480,15 +2501,6 @@
|
||||||
<header>CEditorGLWidget.h</header>
|
<header>CEditorGLWidget.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>WColorPicker</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>WColorPicker.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
<slots>
|
|
||||||
<signal>colorChanged(QColor)</signal>
|
|
||||||
</slots>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>WDraggableSpinBox</class>
|
<class>WDraggableSpinBox</class>
|
||||||
<extends>QDoubleSpinBox</extends>
|
<extends>QDoubleSpinBox</extends>
|
||||||
|
|
Loading…
Reference in New Issue