diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ce633f..f34f473 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ add_subdirectory(common) add_subdirectory(mapeditor) add_subdirectory(mdlviewer) add_subdirectory(launcher) +add_subdirectory(mateditor) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/mateditor/CMakeLists.txt b/mateditor/CMakeLists.txt new file mode 100644 index 0000000..407afc1 --- /dev/null +++ b/mateditor/CMakeLists.txt @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2024 Joshua Goins +# SPDX-License-Identifier: CC0-1.0 + +add_executable(novus-mateditor) +target_sources(novus-mateditor + PRIVATE + include/mainwindow.h + include/materialpropertyedit.h + include/materialview.h + + src/main.cpp + src/mainwindow.cpp + src/materialpropertyedit.cpp + src/materialview.cpp) +target_include_directories(novus-mateditor + PUBLIC + include) +target_link_libraries(novus-mateditor + PRIVATE + Novus::Common + Novus::MdlPart + Physis::Physis + Physis::Logger + Qt6::Core + Qt6::Widgets) + +install(TARGETS novus-mateditor ${KF${QT_MAJOR_VERSION}_INSTALL_TARGETS_DEFAULT_ARGS}) + +if (WIN32) + set_target_properties(novus-mateditor PROPERTIES + WIN32_EXECUTABLE TRUE + OUTPUT_NAME "MaterialEdtiro") + + install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() \ No newline at end of file diff --git a/mateditor/include/mainwindow.h b/mateditor/include/mainwindow.h new file mode 100644 index 0000000..b9777f6 --- /dev/null +++ b/mateditor/include/mainwindow.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "filecache.h" +#include "novusmainwindow.h" + +struct GameData; + +class MainWindow : public NovusMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(GameData *data); + +private: + GameData *data = nullptr; + FileCache cache; + physis_Material m_material; +}; \ No newline at end of file diff --git a/mateditor/include/materialpropertyedit.h b/mateditor/include/materialpropertyedit.h new file mode 100644 index 0000000..a7579c1 --- /dev/null +++ b/mateditor/include/materialpropertyedit.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include + +class MaterialPropertyEdit : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialPropertyEdit(QWidget *parent = nullptr); + + void setMaterial(physis_Material material); + +private: + void rebuild(); + + QVBoxLayout *m_itemsLayout = nullptr; + QLineEdit *m_shaderPackageName = nullptr; + + physis_Material m_material; +}; diff --git a/mateditor/include/materialview.h b/mateditor/include/materialview.h new file mode 100644 index 0000000..374f7d8 --- /dev/null +++ b/mateditor/include/materialview.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "filecache.h" +#include "mdlpart.h" +#include +#include +#include + +struct GameData; + +class MaterialView : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialView(GameData *data, FileCache &cache, QWidget *parent = nullptr); + + MDLPart &part() const; + +public Q_SLOTS: + void addSphere(physis_Material material); + +private: + MDLPart *mdlPart = nullptr; + + GameData *data; + FileCache &cache; + + physis_MDL m_mdl; +}; \ No newline at end of file diff --git a/mateditor/src/main.cpp b/mateditor/src/main.cpp new file mode 100644 index 0000000..308a2ce --- /dev/null +++ b/mateditor/src/main.cpp @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include +#include + +#include "aboutdata.h" +#include "mainwindow.h" +#include "settings.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + KLocalizedString::setApplicationDomain(QByteArrayLiteral("novus")); + + customizeAboutData(QStringLiteral("mateditor"), + QStringLiteral("zone.xiv.mateditor"), + QStringLiteral("Material Editor"), + i18n("Program to view FFXIV materials.")); + + // Default to a sensible message pattern + if (qEnvironmentVariableIsEmpty("QT_MESSAGE_PATTERN")) { + qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); + } + + setup_physis_logging(); + + const QString gameDir{getGameDirectory()}; + const std::string gameDirStd{gameDir.toStdString()}; + MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); + w.show(); + + return app.exec(); +} \ No newline at end of file diff --git a/mateditor/src/mainwindow.cpp b/mateditor/src/mainwindow.cpp new file mode 100644 index 0000000..c0123d9 --- /dev/null +++ b/mateditor/src/mainwindow.cpp @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "mainwindow.h" + +#include +#include +#include +#include +#include + +#include "materialpropertyedit.h" +#include "materialview.h" + +MainWindow::MainWindow(GameData *data) + : NovusMainWindow() + , data(data) + , cache(*data) +{ + setMinimumSize(1280, 720); + setupMenubar(); + + auto matFile = physis_gamedata_extract_file(data, "chara/equipment/e0028/material/v0020/mt_c0101e0028_top_a.mtrl"); + m_material = physis_material_parse(matFile); + + auto dummyWidget = new QSplitter(); + dummyWidget->setChildrenCollapsible(false); + setCentralWidget(dummyWidget); + + auto materialProperty = new MaterialPropertyEdit(); + materialProperty->setMaximumWidth(400); + materialProperty->setMaterial(m_material); + dummyWidget->addWidget(materialProperty); + + auto matView = new MaterialView(data, cache); + matView->addSphere(m_material); + dummyWidget->addWidget(matView); +} + +#include "moc_mainwindow.cpp" \ No newline at end of file diff --git a/mateditor/src/materialpropertyedit.cpp b/mateditor/src/materialpropertyedit.cpp new file mode 100644 index 0000000..9c5f6b4 --- /dev/null +++ b/mateditor/src/materialpropertyedit.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "materialpropertyedit.h" + +#include +#include +#include + +MaterialPropertyEdit::MaterialPropertyEdit(QWidget *parent) + : QWidget(parent) +{ + m_itemsLayout = new QVBoxLayout(this); + + auto shaderPackageLayout = new QHBoxLayout(); + m_itemsLayout->addLayout(shaderPackageLayout); + + m_shaderPackageName = new QLineEdit(); + m_shaderPackageName->setReadOnly(true); + shaderPackageLayout->addWidget(m_shaderPackageName); + + auto selectShaderPackageButton = new QPushButton(i18n("Shaders…")); + shaderPackageLayout->addWidget(selectShaderPackageButton); + + setLayout(m_itemsLayout); + + rebuild(); +} + +void MaterialPropertyEdit::setMaterial(physis_Material material) +{ + m_shaderPackageName->setText(QString::fromLatin1(material.shpk_name)); +} + +void MaterialPropertyEdit::rebuild() +{ +} + +#include "moc_materialpropertyedit.cpp" diff --git a/mateditor/src/materialview.cpp b/mateditor/src/materialview.cpp new file mode 100644 index 0000000..d137ed7 --- /dev/null +++ b/mateditor/src/materialview.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2024 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "materialview.h" + +#include +#include + +#include "filecache.h" + +MaterialView::MaterialView(GameData *data, FileCache &cache, QWidget *parent) + : QWidget(parent) + , data(data) + , cache(cache) +{ + mdlPart = new MDLPart(data, cache); + + auto plateMdlFile = physis_gamedata_extract_file(data, "chara/equipment/e0028/model/c0101e0028_top.mdl"); + m_mdl = physis_mdl_parse(plateMdlFile); + + auto layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(mdlPart); + setLayout(layout); +} + +MDLPart &MaterialView::part() const +{ + return *mdlPart; +} + +void MaterialView::addSphere(physis_Material material) +{ + mdlPart->clear(); + + mdlPart->addModel(m_mdl, false, glm::vec3(), QStringLiteral(""), {material}, 0); +} + +#include "moc_materialview.cpp"