1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-25 05:17:44 +00:00

Add .clang-format and format mdlviewer

This commit is contained in:
Joshua Goins 2023-07-07 16:16:21 -04:00
parent 97dda3d091
commit d67a63710d
17 changed files with 326 additions and 351 deletions

33
.clang-format Normal file
View file

@ -0,0 +1,33 @@
---
AllowShortIfStatementsOnASingleLine: Never
CompactNamespaces: 'false'
DisableFormat: 'false'
IndentCaseLabels: 'true'
IndentPPDirectives: BeforeHash
IndentWidth: '4'
Language: Cpp
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments: 'true'
SortIncludes: 'true'
SortUsingDeclarations: 'true'
SpacesInCStyleCastParentheses: 'false'
Standard: Cpp11
TabWidth: '0'
UseTab: Never
AllowShortEnumsOnASingleLine: false
BraceWrapping:
AfterEnum: true
AccessModifierOffset: -4
SpaceAfterTemplateKeyword: 'false'
AllowAllParametersOfDeclarationOnNextLine: false
AlignAfterOpenBracket: AlwaysBreak
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 120
AllowShortBlocksOnASingleLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: 'Empty'
AllowShortLambdasOnASingleLine: 'Empty'
AllowShortLoopsOnASingleLine: 'false'
SeparateDefinitionBlocks: 'Always'

View file

@ -1,8 +1,8 @@
#pragma once
#include <QDoubleSpinBox>
#include <QWidget>
#include <physis.hpp>
#include <QDoubleSpinBox>
class RaceTreeData : public QObject {
Q_OBJECT

View file

@ -30,7 +30,7 @@ Q_SIGNALS:
std::optional<GearInfo> bottomSlot;
GearView* gearView = nullptr;
QComboBox *raceCombo, *genderCombo;
QComboBox *raceCombo, *subraceCombo, *genderCombo;
GameData* data = nullptr;
physis_CMP cmp;

View file

@ -1,10 +1,10 @@
#pragma once
#include <QWidget>
#include <physis.hpp>
#include <fmt/format.h>
#include <QComboBox>
#include "mdlpart.h"
#include <QComboBox>
#include <QWidget>
#include <fmt/format.h>
#include <physis.hpp>
struct ModelInfo {
int primaryID;
@ -17,7 +17,8 @@ struct GearInfo {
ModelInfo modelInfo;
std::string getMtrlPath(int raceID) {
return fmt::format("chara/equipment/e{gearId:04d}/material/v{gearVersion:04d}/mt_c{raceId:04d}e{gearId:04d}_{slot}_a.mtrl",
return fmt::format(
"chara/equipment/e{gearId:04d}/material/v{gearVersion:04d}/mt_c{raceId:04d}e{gearId:04d}_{slot}_a.mtrl",
fmt::arg("gearId", modelInfo.primaryID),
fmt::arg("gearVersion", modelInfo.gearVersion),
fmt::arg("raceId", raceID),

View file

@ -6,8 +6,8 @@
#include <physis.hpp>
#include <unordered_map>
#include "gearview.h"
#include "fullmodelviewer.h"
#include "gearview.h"
#include "singlegearview.h"
struct GameData;

View file

@ -1,8 +1,8 @@
#pragma once
#include <QWidget>
#include <QPushButton>
#include "gearview.h"
#include <QPushButton>
#include <QWidget>
struct GameData;

View file

@ -7,11 +7,15 @@
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include "vec3edit.h"
#include "quaternionedit.h"
#include "gearview.h"
#include "quaternionedit.h"
#include "vec3edit.h"
void addItem(physis_Skeleton& skeleton, physis_Bone& bone, QTreeWidget* widget, QTreeWidgetItem* parent_item = nullptr) {
void addItem(
physis_Skeleton& skeleton,
physis_Bone& bone,
QTreeWidget* widget,
QTreeWidgetItem* parent_item = nullptr) {
auto item = new QTreeWidgetItem();
item->setText(0, bone.name);
@ -27,18 +31,15 @@ void addItem(physis_Skeleton& skeleton, physis_Bone& bone, QTreeWidget* widget,
}
}
BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
: gearView(gearView) {
BoneEditor::BoneEditor(GearView* gearView, QWidget* parent) : gearView(gearView) {
auto layout = new QHBoxLayout();
setLayout(layout);
auto boneListWidget = new QTreeWidget();
connect(gearView, &GearView::modelReloaded, this,
[this, boneListWidget, gearView] {
connect(gearView, &GearView::modelReloaded, this, [this, boneListWidget, gearView] {
boneListWidget->clear();
addItem(*gearView->part().skeleton,
*gearView->part().skeleton->root_bone, boneListWidget);
addItem(*gearView->part().skeleton, *gearView->part().skeleton->root_bone, boneListWidget);
});
boneListWidget->setMaximumWidth(200);
@ -52,30 +53,26 @@ BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
posEdit = new Vector3Edit(currentPosition);
connect(posEdit, &Vector3Edit::onValueChanged, [this, gearView] {
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition),
sizeof(float) * 3);
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition), sizeof(float) * 3);
gearView->part().reloadRenderer();
});
transformGroupLayout->addRow("Position", posEdit);
rotationEdit = new QuaternionEdit(currentRotation);
connect(rotationEdit, &QuaternionEdit::onValueChanged, [this, gearView] {
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation),
sizeof(float) * 4);
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation), sizeof(float) * 4);
gearView->part().reloadRenderer();
});
transformGroupLayout->addRow("Rotation", rotationEdit);
scaleEdit = new Vector3Edit(currentScale);
connect(scaleEdit, &Vector3Edit::onValueChanged, [this, gearView] {
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale),
sizeof(float) * 3);
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale), sizeof(float) * 3);
gearView->part().reloadRenderer();
});
transformGroupLayout->addRow("Scale", scaleEdit);
connect(boneListWidget, &QTreeWidget::itemClicked, this,
&BoneEditor::treeItemClicked);
connect(boneListWidget, &QTreeWidget::itemClicked, this, &BoneEditor::treeItemClicked);
auto raceDeformGroup = new QGroupBox("Race Deform");
layout->addWidget(raceDeformGroup);
@ -95,8 +92,7 @@ BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
void BoneEditor::treeItemClicked(QTreeWidgetItem* item, int column) {
auto& skeleton = *gearView->part().skeleton;
for (int i = 0; i < skeleton.num_bones; i++) {
if (strcmp(skeleton.bones[i].name,
item->text(column).toStdString().c_str()) == 0) {
if (strcmp(skeleton.bones[i].name, item->text(column).toStdString().c_str()) == 0) {
currentPosition = glm::make_vec3(skeleton.bones[i].position);
currentRotation = glm::make_quat(skeleton.bones[i].rotation);
currentScale = glm::make_vec3(skeleton.bones[i].scale);
@ -112,8 +108,8 @@ void BoneEditor::treeItemClicked(QTreeWidgetItem *item, int column) {
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(gearView->part().boneData[i].deformRaceMatrix, scale,
rotation, translation, skew, perspective);
glm::decompose(
gearView->part().boneData[i].deformRaceMatrix, scale, rotation, translation, skew, perspective);
currentRacePosition = translation;
currentRaceRotation = rotation;

View file

@ -1,9 +1,9 @@
#include "cmpeditor.h"
#include <QTreeWidget>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QTreeWidget>
#include "magic_enum.hpp"
@ -14,63 +14,14 @@ struct RaceTree {
};
std::vector<RaceTree> raceTree = {
{
Race::Hyur,
{
Subrace::Midlander,
Subrace::Highlander
}
},
{
Race::Elezen,
{
Subrace::Wildwood,
Subrace::Duskwight
}
},
{
Race::Miqote,
{
Subrace::Seeker,
Subrace::Keeper
}
},
{
Race::Roegadyn,
{
Subrace::SeaWolf,
Subrace::Hellion
}
},
{
Race::Lalafell,
{
Subrace::Plainsfolk,
Subrace::Dunesfolk
}
},
{
Race::AuRa,
{
Subrace::Raen,
Subrace::Xaela
}
},
{
Race::Hrothgar,
{
Subrace::Hellion,
Subrace::Lost
}
},
{
Race::Viera,
{
Subrace::Rava,
Subrace::Veena
}
}
};
{Race::Hyur, {Subrace::Midlander, Subrace::Highlander}},
{Race::Elezen, {Subrace::Wildwood, Subrace::Duskwight}},
{Race::Miqote, {Subrace::Seeker, Subrace::Keeper}},
{Race::Roegadyn, {Subrace::SeaWolf, Subrace::Hellion}},
{Race::Lalafell, {Subrace::Plainsfolk, Subrace::Dunesfolk}},
{Race::AuRa, {Subrace::Raen, Subrace::Xaela}},
{Race::Hrothgar, {Subrace::Hellion, Subrace::Lost}},
{Race::Viera, {Subrace::Rava, Subrace::Veena}}};
CmpEditor::CmpEditor(GameData* data) : data(data) {
auto layout = new QHBoxLayout();

View file

@ -14,14 +14,12 @@ FullModelViewer::FullModelViewer(GameData *data) : data(data) {
auto layout = new QVBoxLayout();
setLayout(layout);
cmp = physis_cmp_parse(
physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp"));
cmp = physis_cmp_parse(physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp"));
gearView = new GearView(data);
updateCharacterParameters();
connect(gearView, &GearView::modelReloaded, this,
&FullModelViewer::updateCharacterParameters);
connect(gearView, &GearView::modelReloaded, this, &FullModelViewer::updateCharacterParameters);
auto viewportLayout = new QHBoxLayout();
viewportLayout->addWidget(gearView, 1);
@ -58,8 +56,9 @@ FullModelViewer::FullModelViewer(GameData *data) : data(data) {
layout->addLayout(controlLayout);
raceCombo = new QComboBox();
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
[this](int index) { gearView->setRace((Race)index); });
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
gearView->setRace((Race)index);
});
controlLayout->addWidget(raceCombo);
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
@ -134,15 +133,13 @@ void FullModelViewer::updateHeightScaling(float scale) {
for (int i = 0; i < boneData.num_bones; i++) {
const std::string_view name{boneData.bones[i].name};
if (name == "n_root") {
auto racialScaling = physis_cmp_get_racial_scaling_parameters(
cmp, gearView->currentRace, gearView->currentSubrace);
auto racialScaling =
physis_cmp_get_racial_scaling_parameters(cmp, gearView->currentRace, gearView->currentSubrace);
const float minSize = gearView->currentGender == Gender::Male
? racialScaling.male_min_size
: racialScaling.female_min_size;
const float maxSize = gearView->currentGender == Gender::Male
? racialScaling.male_max_size
: racialScaling.female_max_size;
const float minSize =
gearView->currentGender == Gender::Male ? racialScaling.male_min_size : racialScaling.female_min_size;
const float maxSize =
gearView->currentGender == Gender::Male ? racialScaling.male_max_size : racialScaling.female_max_size;
const float size = glm::mix(minSize, maxSize, scale);
@ -162,15 +159,12 @@ void FullModelViewer::updateBustScaling(float scale) {
for (int i = 0; i < boneData.num_bones; i++) {
const std::string_view name{boneData.bones[i].name};
if (name == "j_mune_l" || name == "j_mune_r") {
auto racialScaling = physis_cmp_get_racial_scaling_parameters(
cmp, gearView->currentRace, gearView->currentSubrace);
auto racialScaling =
physis_cmp_get_racial_scaling_parameters(cmp, gearView->currentRace, gearView->currentSubrace);
const float rangeX = glm::mix(racialScaling.bust_min_x,
racialScaling.bust_max_x, scale);
const float rangeY = glm::mix(racialScaling.bust_min_y,
racialScaling.bust_max_y, scale);
const float rangeZ = glm::mix(racialScaling.bust_min_z,
racialScaling.bust_max_z, scale);
const float rangeX = glm::mix(racialScaling.bust_min_x, racialScaling.bust_max_x, scale);
const float rangeY = glm::mix(racialScaling.bust_min_y, racialScaling.bust_max_y, scale);
const float rangeZ = glm::mix(racialScaling.bust_min_z, racialScaling.bust_max_z, scale);
boneData.bones[i].scale[0] = rangeX;
boneData.bones[i].scale[1] = rangeY;

View file

@ -1,8 +1,8 @@
#include "gearview.h"
#include "magic_enum.hpp"
#include <QVBoxLayout>
#include <QDebug>
#include <QVBoxLayout>
GearView::GearView(GameData* data) : data(data) {
mdlPart = new MDLPart(data);
@ -13,7 +13,9 @@ GearView::GearView(GameData *data) : data(data) {
layout->addWidget(mdlPart);
setLayout(layout);
connect(this, &GearView::gearChanged, this, [=] { reloadModel(); });
connect(this, &GearView::gearChanged, this, [=] {
reloadModel();
});
connect(this, &GearView::raceChanged, this, [=] {
reloadRaceDeforms();
@ -31,8 +33,8 @@ std::vector<std::pair<Race, Subrace>> GearView::supportedRaces() const {
for (const auto& gear : gears) {
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
for (auto subrace : physis_get_supported_subraces(race).subraces) {
auto equip_path = physis_build_equipment_path(
gear.modelInfo.primaryID, race, subrace, currentGender, gear.slot);
auto equip_path =
physis_build_equipment_path(gear.modelInfo.primaryID, race, subrace, currentGender, gear.slot);
if (physis_gamedata_exists(data, equip_path))
races.emplace_back(race, subrace);
@ -47,7 +49,8 @@ std::vector<Gender> GearView::supportedGenders() const {
std::vector<Gender> genders;
for (const auto& gear : gears) {
for (auto [gender, gender_name] : magic_enum::enum_entries<Gender>()) {
auto equip_path = physis_build_equipment_path(gear.modelInfo.primaryID, currentRace, Subrace::Midlander, currentGender, gear.slot);
auto equip_path = physis_build_equipment_path(
gear.modelInfo.primaryID, currentRace, Subrace::Midlander, currentGender, gear.slot);
if (physis_gamedata_exists(data, equip_path))
genders.push_back(gender);
@ -87,8 +90,7 @@ void GearView::setRace(Race race) {
currentRace = race;
auto supportedSubraces = physis_get_supported_subraces(race);
if (supportedSubraces.subraces[0] == currentSubrace ||
supportedSubraces.subraces[1] == currentSubrace) {
if (supportedSubraces.subraces[0] == currentSubrace || supportedSubraces.subraces[1] == currentSubrace) {
} else {
setSubrace(supportedSubraces.subraces[0]);
}
@ -130,9 +132,9 @@ void GearView::reloadModel() {
for (const auto& gear : gears) {
auto mdl_data = physis_gamedata_extract_file(
data, physis_build_equipment_path(gear.modelInfo.primaryID,
currentRace, currentSubrace,
currentGender, gear.slot));
data,
physis_build_equipment_path(
gear.modelInfo.primaryID, currentRace, currentSubrace, currentGender, gear.slot));
// attempt to load the next best race
// currently hardcoded to hyur midlander
@ -140,9 +142,9 @@ void GearView::reloadModel() {
Subrace fallbackSubrace = currentSubrace;
if (mdl_data.size == 0) {
mdl_data = physis_gamedata_extract_file(
data, physis_build_equipment_path(
gear.modelInfo.primaryID, Race::Hyur,
Subrace::Midlander, currentGender, gear.slot));
data,
physis_build_equipment_path(
gear.modelInfo.primaryID, Race::Hyur, Subrace::Midlander, currentGender, gear.slot));
fallbackRace = Race::Hyur;
fallbackSubrace = Subrace::Midlander;
}
@ -159,7 +161,8 @@ void GearView::reloadModel() {
std::string mtrl_path = fmt::format(
"chara/equipment/e{gearId:04d}/material/"
"v{gearVersion:04d}{}",
material_name, fmt::arg("gearId", gear.modelInfo.primaryID),
material_name,
fmt::arg("gearId", gear.modelInfo.primaryID),
fmt::arg("gearVersion", gear.modelInfo.gearVersion));
int bodyCode = 1;
@ -169,9 +172,7 @@ void GearView::reloadModel() {
"chara/human/c{raceCode:04d}/obj/body/b{bodyCode:04d}/"
"material/v0001{}",
material_name,
fmt::arg("raceCode",
physis_get_race_code(fallbackRace, fallbackSubrace,
currentGender)),
fmt::arg("raceCode", physis_get_race_code(fallbackRace, fallbackSubrace, currentGender)),
fmt::arg("bodyCode", bodyCode));
if (physis_gamedata_exists(data, mtrl_path.c_str())) {
@ -195,25 +196,18 @@ void GearView::reloadModel() {
}
void GearView::reloadRaceDeforms() {
qDebug() << "Loading race deform matrices for "
<< magic_enum::enum_name(currentRace).data()
<< magic_enum::enum_name(currentSubrace).data()
<< magic_enum::enum_name(currentGender).data();
const int raceCode =
physis_get_race_code(currentRace, currentSubrace, currentGender);
qDebug() << "Loading race deform matrices for " << magic_enum::enum_name(currentRace).data()
<< magic_enum::enum_name(currentSubrace).data() << magic_enum::enum_name(currentGender).data();
const int raceCode = physis_get_race_code(currentRace, currentSubrace, currentGender);
qDebug() << "Race code: " << raceCode;
QString skelName =
QString{"c%1b0001.skel"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
mdlPart->setSkeleton(physis_skeleton_from_skel(
physis_read_file(skelName.toStdString().c_str())));
QString skelName = QString{"c%1b0001.skel"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
mdlPart->setSkeleton(physis_skeleton_from_skel(physis_read_file(skelName.toStdString().c_str())));
// racial deforms don't work on Hyur, not needed? TODO not sure
if (currentRace != Race::Hyur) {
QString deformName =
QString{"c%1_deform.json"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
mdlPart->loadRaceDeformMatrices(
physis_read_file(deformName.toStdString().c_str()));
QString deformName = QString{"c%1_deform.json"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
mdlPart->loadRaceDeformMatrices(physis_read_file(deformName.toStdString().c_str()));
} else {
for (auto& data : mdlPart->boneData) {
data.deformRaceMatrix = glm::mat4(1.0f);
@ -221,6 +215,8 @@ void GearView::reloadRaceDeforms() {
}
}
MDLPart &GearView::part() const { return *mdlPart; }
MDLPart& GearView::part() const {
return *mdlPart;
}
#include "moc_gearview.cpp"

View file

@ -1,18 +1,18 @@
#include "mainwindow.h"
#include <QHBoxLayout>
#include <QTableWidget>
#include <QListWidget>
#include <QLineEdit>
#include <QListWidget>
#include <QTableWidget>
#include <QTimer>
#include <QPushButton>
#include <QFileDialog>
#include <magic_enum.hpp>
#include <QMenuBar>
#include <QAction>
#include <glm/gtc/type_ptr.hpp>
#include <QFileDialog>
#include <QMenuBar>
#include <QPushButton>
#include <QTreeWidget>
#include <glm/gtc/type_ptr.hpp>
#include <magic_enum.hpp>
#include <physis.hpp>
#include "cmpeditor.h"

View file

@ -1,8 +1,8 @@
#include "singlegearview.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QFileDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include "magic_enum.hpp"
@ -17,8 +17,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
layout->addLayout(controlLayout);
raceCombo = new QComboBox();
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
[this](int index) {
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
if (loadingComboData)
return;
@ -27,8 +26,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
controlLayout->addWidget(raceCombo);
subraceCombo = new QComboBox();
connect(subraceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
[this](int index) {
connect(subraceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
if (loadingComboData)
return;
@ -37,8 +35,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
controlLayout->addWidget(subraceCombo);
genderCombo = new QComboBox();
connect(genderCombo, qOverload<int>(&QComboBox::currentIndexChanged),
[this](int index) {
connect(genderCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
if (loadingComboData)
return;
@ -65,9 +62,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
exportButton = new QPushButton("Export...");
connect(exportButton, &QPushButton::clicked, this, [this](bool) {
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"),
"model.fbx",
tr("FBX Files (*.fbx)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"), "model.fbx", tr("FBX Files (*.fbx)"));
gearView->exportModel(fileName);
});

View file

@ -27,15 +27,24 @@ Vector3Edit::Vector3Edit(glm::vec3& vec, QWidget* parent) : QWidget(parent), vec
spinBoxes.y->setValue(vec.y);
spinBoxes.z->setValue(vec.z);
connect(spinBoxes.x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this, &vec](double d) {
connect(
spinBoxes.x,
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
[this, &vec](double d) {
vec.x = d;
emit onValueChanged();
});
connect(spinBoxes.y, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this, &vec](double d) {
connect(
spinBoxes.y,
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
[this, &vec](double d) {
vec.y = d;
emit onValueChanged();
});
connect(spinBoxes.z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this, &vec](double d) {
connect(
spinBoxes.z,
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
[this, &vec](double d) {
vec.z = d;
emit onValueChanged();
});