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:
parent
97dda3d091
commit
d67a63710d
17 changed files with 326 additions and 351 deletions
33
.clang-format
Normal file
33
.clang-format
Normal 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'
|
|
@ -12,31 +12,31 @@
|
||||||
class GearView;
|
class GearView;
|
||||||
|
|
||||||
class BoneEditor : public QWidget {
|
class BoneEditor : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BoneEditor(GearView *gearView, QWidget *parent = nullptr);
|
explicit BoneEditor(GearView* gearView, QWidget* parent = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void treeItemClicked(QTreeWidgetItem *item, int column);
|
void treeItemClicked(QTreeWidgetItem* item, int column);
|
||||||
|
|
||||||
GearView *gearView;
|
GearView* gearView;
|
||||||
|
|
||||||
glm::vec3 currentPosition;
|
glm::vec3 currentPosition;
|
||||||
glm::quat currentRotation;
|
glm::quat currentRotation;
|
||||||
glm::vec3 currentScale;
|
glm::vec3 currentScale;
|
||||||
|
|
||||||
glm::vec3 currentRacePosition;
|
glm::vec3 currentRacePosition;
|
||||||
glm::quat currentRaceRotation;
|
glm::quat currentRaceRotation;
|
||||||
glm::vec3 currentRaceScale;
|
glm::vec3 currentRaceScale;
|
||||||
|
|
||||||
physis_Bone *currentEditedBone;
|
physis_Bone* currentEditedBone;
|
||||||
|
|
||||||
Vector3Edit *posEdit;
|
Vector3Edit* posEdit;
|
||||||
QuaternionEdit *rotationEdit;
|
QuaternionEdit* rotationEdit;
|
||||||
Vector3Edit *scaleEdit;
|
Vector3Edit* scaleEdit;
|
||||||
|
|
||||||
Vector3Edit *raceDeformPosEdit;
|
Vector3Edit* raceDeformPosEdit;
|
||||||
QuaternionEdit *raceDeformRotationEdit;
|
QuaternionEdit* raceDeformRotationEdit;
|
||||||
Vector3Edit *raceDeformScaleEdit;
|
Vector3Edit* raceDeformScaleEdit;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <physis.hpp>
|
#include <physis.hpp>
|
||||||
#include <QDoubleSpinBox>
|
|
||||||
|
|
||||||
class RaceTreeData : public QObject {
|
class RaceTreeData : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -14,14 +14,14 @@ public:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void gearChanged();
|
void gearChanged();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void clear();
|
void clear();
|
||||||
void addGear(GearInfo &info);
|
void addGear(GearInfo& info);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void reloadGear();
|
void reloadGear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHeightScaling(float scale);
|
void updateHeightScaling(float scale);
|
||||||
void updateBustScaling(float scale);
|
void updateBustScaling(float scale);
|
||||||
void updateCharacterParameters();
|
void updateCharacterParameters();
|
||||||
|
@ -29,10 +29,10 @@ Q_SIGNALS:
|
||||||
std::optional<GearInfo> topSlot;
|
std::optional<GearInfo> topSlot;
|
||||||
std::optional<GearInfo> bottomSlot;
|
std::optional<GearInfo> bottomSlot;
|
||||||
|
|
||||||
GearView *gearView = nullptr;
|
GearView* gearView = nullptr;
|
||||||
QComboBox *raceCombo, *genderCombo;
|
QComboBox *raceCombo, *subraceCombo, *genderCombo;
|
||||||
|
|
||||||
GameData *data = nullptr;
|
GameData* data = nullptr;
|
||||||
physis_CMP cmp;
|
physis_CMP cmp;
|
||||||
|
|
||||||
float heightScale = 0.5f;
|
float heightScale = 0.5f;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <physis.hpp>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include "mdlpart.h"
|
#include "mdlpart.h"
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <physis.hpp>
|
||||||
|
|
||||||
struct ModelInfo {
|
struct ModelInfo {
|
||||||
int primaryID;
|
int primaryID;
|
||||||
|
@ -17,11 +17,12 @@ struct GearInfo {
|
||||||
ModelInfo modelInfo;
|
ModelInfo modelInfo;
|
||||||
|
|
||||||
std::string getMtrlPath(int raceID) {
|
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(
|
||||||
fmt::arg("gearId", modelInfo.primaryID),
|
"chara/equipment/e{gearId:04d}/material/v{gearVersion:04d}/mt_c{raceId:04d}e{gearId:04d}_{slot}_a.mtrl",
|
||||||
fmt::arg("gearVersion", modelInfo.gearVersion),
|
fmt::arg("gearId", modelInfo.primaryID),
|
||||||
fmt::arg("raceId", raceID),
|
fmt::arg("gearVersion", modelInfo.gearVersion),
|
||||||
fmt::arg("slot", physis_get_slot_name(slot)));
|
fmt::arg("raceId", raceID),
|
||||||
|
fmt::arg("slot", physis_get_slot_name(slot)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,15 +42,15 @@ public:
|
||||||
/// Returns an inclusive list of LoDs supported by the current gearset.
|
/// Returns an inclusive list of LoDs supported by the current gearset.
|
||||||
int lodCount() const;
|
int lodCount() const;
|
||||||
|
|
||||||
void exportModel(const QString &fileName);
|
void exportModel(const QString& fileName);
|
||||||
|
|
||||||
MDLPart &part() const;
|
MDLPart& part() const;
|
||||||
|
|
||||||
Race currentRace = Race::Hyur;
|
Race currentRace = Race::Hyur;
|
||||||
Subrace currentSubrace = Subrace::Midlander;
|
Subrace currentSubrace = Subrace::Midlander;
|
||||||
Gender currentGender = Gender::Male;
|
Gender currentGender = Gender::Male;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void gearChanged();
|
void gearChanged();
|
||||||
void modelReloaded();
|
void modelReloaded();
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ public:
|
||||||
void genderChanged();
|
void genderChanged();
|
||||||
void levelOfDetailChanged();
|
void levelOfDetailChanged();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void clear();
|
void clear();
|
||||||
void addGear(GearInfo& gear);
|
void addGear(GearInfo& gear);
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ public:
|
||||||
void reloadModel();
|
void reloadModel();
|
||||||
void reloadRaceDeforms();
|
void reloadRaceDeforms();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int currentLod = 0;
|
int currentLod = 0;
|
||||||
|
|
||||||
uint32_t maxLod = 0;
|
uint32_t maxLod = 0;
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include <physis.hpp>
|
#include <physis.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "gearview.h"
|
|
||||||
#include "fullmodelviewer.h"
|
#include "fullmodelviewer.h"
|
||||||
|
#include "gearview.h"
|
||||||
#include "singlegearview.h"
|
#include "singlegearview.h"
|
||||||
|
|
||||||
struct GameData;
|
struct GameData;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class QuaternionEdit : public QWidget {
|
class QuaternionEdit : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QuaternionEdit(glm::quat& quat, QWidget* parent = nullptr);
|
explicit QuaternionEdit(glm::quat& quat, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include "gearview.h"
|
#include "gearview.h"
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
struct GameData;
|
struct GameData;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ private:
|
||||||
Gender currentGender = Gender::Female;
|
Gender currentGender = Gender::Female;
|
||||||
int currentLod = 0;
|
int currentLod = 0;
|
||||||
|
|
||||||
GearView *gearView = nullptr;
|
GearView* gearView = nullptr;
|
||||||
QComboBox *raceCombo, *subraceCombo, *genderCombo, *lodCombo;
|
QComboBox *raceCombo, *subraceCombo, *genderCombo, *lodCombo;
|
||||||
QPushButton *addToFMVButton, *exportButton;
|
QPushButton *addToFMVButton, *exportButton;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class Vector3Edit : public QWidget {
|
class Vector3Edit : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Vector3Edit(glm::vec3& vec, QWidget* parent = nullptr);
|
explicit Vector3Edit(glm::vec3& vec, QWidget* parent = nullptr);
|
||||||
~Vector3Edit();
|
~Vector3Edit();
|
||||||
|
|
|
@ -7,39 +7,40 @@
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtx/matrix_decompose.hpp>
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
|
||||||
#include "vec3edit.h"
|
|
||||||
#include "quaternionedit.h"
|
|
||||||
#include "gearview.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();
|
auto item = new QTreeWidgetItem();
|
||||||
item->setText(0, bone.name);
|
item->setText(0, bone.name);
|
||||||
|
|
||||||
if(parent_item == nullptr) {
|
if (parent_item == nullptr) {
|
||||||
widget->addTopLevelItem(item);
|
widget->addTopLevelItem(item);
|
||||||
} else {
|
} else {
|
||||||
parent_item->addChild(item);
|
parent_item->addChild(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < skeleton.num_bones; i++) {
|
for (int i = 0; i < skeleton.num_bones; i++) {
|
||||||
if(skeleton.bones[i].parent_bone != nullptr && strcmp(skeleton.bones[i].parent_bone->name, bone.name) == 0)
|
if (skeleton.bones[i].parent_bone != nullptr && strcmp(skeleton.bones[i].parent_bone->name, bone.name) == 0)
|
||||||
addItem(skeleton, skeleton.bones[i], widget, item);
|
addItem(skeleton, skeleton.bones[i], widget, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
|
BoneEditor::BoneEditor(GearView* gearView, QWidget* parent) : gearView(gearView) {
|
||||||
: gearView(gearView) {
|
|
||||||
auto layout = new QHBoxLayout();
|
auto layout = new QHBoxLayout();
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
auto boneListWidget = new QTreeWidget();
|
auto boneListWidget = new QTreeWidget();
|
||||||
|
|
||||||
connect(gearView, &GearView::modelReloaded, this,
|
connect(gearView, &GearView::modelReloaded, this, [this, boneListWidget, gearView] {
|
||||||
[this, boneListWidget, gearView] {
|
boneListWidget->clear();
|
||||||
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);
|
boneListWidget->setMaximumWidth(200);
|
||||||
|
|
||||||
|
@ -52,30 +53,26 @@ BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
|
||||||
|
|
||||||
posEdit = new Vector3Edit(currentPosition);
|
posEdit = new Vector3Edit(currentPosition);
|
||||||
connect(posEdit, &Vector3Edit::onValueChanged, [this, gearView] {
|
connect(posEdit, &Vector3Edit::onValueChanged, [this, gearView] {
|
||||||
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition),
|
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition), sizeof(float) * 3);
|
||||||
sizeof(float) * 3);
|
gearView->part().reloadRenderer();
|
||||||
gearView->part().reloadRenderer();
|
|
||||||
});
|
});
|
||||||
transformGroupLayout->addRow("Position", posEdit);
|
transformGroupLayout->addRow("Position", posEdit);
|
||||||
|
|
||||||
rotationEdit = new QuaternionEdit(currentRotation);
|
rotationEdit = new QuaternionEdit(currentRotation);
|
||||||
connect(rotationEdit, &QuaternionEdit::onValueChanged, [this, gearView] {
|
connect(rotationEdit, &QuaternionEdit::onValueChanged, [this, gearView] {
|
||||||
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation),
|
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation), sizeof(float) * 4);
|
||||||
sizeof(float) * 4);
|
gearView->part().reloadRenderer();
|
||||||
gearView->part().reloadRenderer();
|
|
||||||
});
|
});
|
||||||
transformGroupLayout->addRow("Rotation", rotationEdit);
|
transformGroupLayout->addRow("Rotation", rotationEdit);
|
||||||
|
|
||||||
scaleEdit = new Vector3Edit(currentScale);
|
scaleEdit = new Vector3Edit(currentScale);
|
||||||
connect(scaleEdit, &Vector3Edit::onValueChanged, [this, gearView] {
|
connect(scaleEdit, &Vector3Edit::onValueChanged, [this, gearView] {
|
||||||
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale),
|
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale), sizeof(float) * 3);
|
||||||
sizeof(float) * 3);
|
gearView->part().reloadRenderer();
|
||||||
gearView->part().reloadRenderer();
|
|
||||||
});
|
});
|
||||||
transformGroupLayout->addRow("Scale", scaleEdit);
|
transformGroupLayout->addRow("Scale", scaleEdit);
|
||||||
|
|
||||||
connect(boneListWidget, &QTreeWidget::itemClicked, this,
|
connect(boneListWidget, &QTreeWidget::itemClicked, this, &BoneEditor::treeItemClicked);
|
||||||
&BoneEditor::treeItemClicked);
|
|
||||||
|
|
||||||
auto raceDeformGroup = new QGroupBox("Race Deform");
|
auto raceDeformGroup = new QGroupBox("Race Deform");
|
||||||
layout->addWidget(raceDeformGroup);
|
layout->addWidget(raceDeformGroup);
|
||||||
|
@ -92,11 +89,10 @@ BoneEditor::BoneEditor(GearView *gearView, QWidget *parent)
|
||||||
raceDeformGroupLayout->addRow("Scale", raceDeformScaleEdit);
|
raceDeformGroupLayout->addRow("Scale", raceDeformScaleEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoneEditor::treeItemClicked(QTreeWidgetItem *item, int column) {
|
void BoneEditor::treeItemClicked(QTreeWidgetItem* item, int column) {
|
||||||
auto &skeleton = *gearView->part().skeleton;
|
auto& skeleton = *gearView->part().skeleton;
|
||||||
for (int i = 0; i < skeleton.num_bones; i++) {
|
for (int i = 0; i < skeleton.num_bones; i++) {
|
||||||
if (strcmp(skeleton.bones[i].name,
|
if (strcmp(skeleton.bones[i].name, item->text(column).toStdString().c_str()) == 0) {
|
||||||
item->text(column).toStdString().c_str()) == 0) {
|
|
||||||
currentPosition = glm::make_vec3(skeleton.bones[i].position);
|
currentPosition = glm::make_vec3(skeleton.bones[i].position);
|
||||||
currentRotation = glm::make_quat(skeleton.bones[i].rotation);
|
currentRotation = glm::make_quat(skeleton.bones[i].rotation);
|
||||||
currentScale = glm::make_vec3(skeleton.bones[i].scale);
|
currentScale = glm::make_vec3(skeleton.bones[i].scale);
|
||||||
|
@ -112,8 +108,8 @@ void BoneEditor::treeItemClicked(QTreeWidgetItem *item, int column) {
|
||||||
glm::vec3 translation;
|
glm::vec3 translation;
|
||||||
glm::vec3 skew;
|
glm::vec3 skew;
|
||||||
glm::vec4 perspective;
|
glm::vec4 perspective;
|
||||||
glm::decompose(gearView->part().boneData[i].deformRaceMatrix, scale,
|
glm::decompose(
|
||||||
rotation, translation, skew, perspective);
|
gearView->part().boneData[i].deformRaceMatrix, scale, rotation, translation, skew, perspective);
|
||||||
|
|
||||||
currentRacePosition = translation;
|
currentRacePosition = translation;
|
||||||
currentRaceRotation = rotation;
|
currentRaceRotation = rotation;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "cmpeditor.h"
|
#include "cmpeditor.h"
|
||||||
|
|
||||||
#include <QTreeWidget>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
|
||||||
#include "magic_enum.hpp"
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
|
@ -14,63 +14,14 @@ struct RaceTree {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RaceTree> raceTree = {
|
std::vector<RaceTree> raceTree = {
|
||||||
{
|
{Race::Hyur, {Subrace::Midlander, Subrace::Highlander}},
|
||||||
Race::Hyur,
|
{Race::Elezen, {Subrace::Wildwood, Subrace::Duskwight}},
|
||||||
{
|
{Race::Miqote, {Subrace::Seeker, Subrace::Keeper}},
|
||||||
Subrace::Midlander,
|
{Race::Roegadyn, {Subrace::SeaWolf, Subrace::Hellion}},
|
||||||
Subrace::Highlander
|
{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::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) {
|
CmpEditor::CmpEditor(GameData* data) : data(data) {
|
||||||
auto layout = new QHBoxLayout();
|
auto layout = new QHBoxLayout();
|
||||||
|
@ -82,7 +33,7 @@ CmpEditor::CmpEditor(GameData* data) : data(data) {
|
||||||
raceListWidget->setMaximumWidth(200);
|
raceListWidget->setMaximumWidth(200);
|
||||||
layout->addWidget(raceListWidget);
|
layout->addWidget(raceListWidget);
|
||||||
|
|
||||||
for(auto race : raceTree) {
|
for (auto race : raceTree) {
|
||||||
auto item = new QTreeWidgetItem();
|
auto item = new QTreeWidgetItem();
|
||||||
item->setText(0, magic_enum::enum_name(race.baseRace).data());
|
item->setText(0, magic_enum::enum_name(race.baseRace).data());
|
||||||
raceListWidget->addTopLevelItem(item);
|
raceListWidget->addTopLevelItem(item);
|
||||||
|
|
|
@ -6,63 +6,62 @@
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
FullModelViewer::FullModelViewer(GameData *data) : data(data) {
|
FullModelViewer::FullModelViewer(GameData* data) : data(data) {
|
||||||
setWindowTitle("Full Model Viewer");
|
setWindowTitle("Full Model Viewer");
|
||||||
setMinimumWidth(640);
|
setMinimumWidth(640);
|
||||||
setMinimumHeight(480);
|
setMinimumHeight(480);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout();
|
auto layout = new QVBoxLayout();
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
cmp = physis_cmp_parse(
|
cmp = physis_cmp_parse(physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp"));
|
||||||
physis_gamedata_extract_file(data, "chara/xls/charamake/human.cmp"));
|
|
||||||
|
|
||||||
gearView = new GearView(data);
|
gearView = new GearView(data);
|
||||||
updateCharacterParameters();
|
updateCharacterParameters();
|
||||||
|
|
||||||
connect(gearView, &GearView::modelReloaded, this,
|
connect(gearView, &GearView::modelReloaded, this, &FullModelViewer::updateCharacterParameters);
|
||||||
&FullModelViewer::updateCharacterParameters);
|
|
||||||
|
|
||||||
auto viewportLayout = new QHBoxLayout();
|
auto viewportLayout = new QHBoxLayout();
|
||||||
viewportLayout->addWidget(gearView, 1);
|
viewportLayout->addWidget(gearView, 1);
|
||||||
layout->addLayout(viewportLayout);
|
layout->addLayout(viewportLayout);
|
||||||
|
|
||||||
auto characterEditorWidget = new QWidget();
|
auto characterEditorWidget = new QWidget();
|
||||||
auto characterEditorLayout = new QFormLayout();
|
auto characterEditorLayout = new QFormLayout();
|
||||||
characterEditorWidget->setLayout(characterEditorLayout);
|
characterEditorWidget->setLayout(characterEditorLayout);
|
||||||
|
|
||||||
auto characterHeight = new QSlider();
|
auto characterHeight = new QSlider();
|
||||||
characterHeight->setOrientation(Qt::Horizontal);
|
characterHeight->setOrientation(Qt::Horizontal);
|
||||||
characterHeight->setSliderPosition(50);
|
characterHeight->setSliderPosition(50);
|
||||||
connect(characterHeight, &QSlider::sliderMoved, this, [this](int position) {
|
connect(characterHeight, &QSlider::sliderMoved, this, [this](int position) {
|
||||||
const float scale = (float)position / 100.0f;
|
const float scale = (float)position / 100.0f;
|
||||||
updateHeightScaling(scale);
|
updateHeightScaling(scale);
|
||||||
});
|
});
|
||||||
characterEditorLayout->addRow("Height", characterHeight);
|
characterEditorLayout->addRow("Height", characterHeight);
|
||||||
|
|
||||||
auto bustSize = new QSlider();
|
auto bustSize = new QSlider();
|
||||||
bustSize->setOrientation(Qt::Horizontal);
|
bustSize->setOrientation(Qt::Horizontal);
|
||||||
bustSize->setSliderPosition(50);
|
bustSize->setSliderPosition(50);
|
||||||
connect(bustSize, &QSlider::sliderMoved, this, [this](int position) {
|
connect(bustSize, &QSlider::sliderMoved, this, [this](int position) {
|
||||||
const float scale = (float)position / 100.0f;
|
const float scale = (float)position / 100.0f;
|
||||||
updateBustScaling(scale);
|
updateBustScaling(scale);
|
||||||
});
|
});
|
||||||
characterEditorLayout->addRow("Bust Size", bustSize);
|
characterEditorLayout->addRow("Bust Size", bustSize);
|
||||||
|
|
||||||
auto tabWidget = new QTabWidget();
|
auto tabWidget = new QTabWidget();
|
||||||
tabWidget->addTab(new BoneEditor(gearView), "Bone Editor");
|
tabWidget->addTab(new BoneEditor(gearView), "Bone Editor");
|
||||||
tabWidget->addTab(characterEditorWidget, "Character Editor");
|
tabWidget->addTab(characterEditorWidget, "Character Editor");
|
||||||
viewportLayout->addWidget(tabWidget);
|
viewportLayout->addWidget(tabWidget);
|
||||||
|
|
||||||
auto controlLayout = new QHBoxLayout();
|
auto controlLayout = new QHBoxLayout();
|
||||||
layout->addLayout(controlLayout);
|
layout->addLayout(controlLayout);
|
||||||
|
|
||||||
raceCombo = new QComboBox();
|
raceCombo = new QComboBox();
|
||||||
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
|
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
[this](int index) { gearView->setRace((Race)index); });
|
gearView->setRace((Race)index);
|
||||||
controlLayout->addWidget(raceCombo);
|
});
|
||||||
|
controlLayout->addWidget(raceCombo);
|
||||||
|
|
||||||
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
|
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
|
||||||
raceCombo->addItem(race_name.data());
|
raceCombo->addItem(race_name.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +87,8 @@ void FullModelViewer::clear() {
|
||||||
Q_EMIT gearChanged();
|
Q_EMIT gearChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullModelViewer::addGear(GearInfo &info) {
|
void FullModelViewer::addGear(GearInfo& info) {
|
||||||
switch(info.slot) {
|
switch (info.slot) {
|
||||||
case Slot::Body:
|
case Slot::Body:
|
||||||
topSlot = info;
|
topSlot = info;
|
||||||
break;
|
break;
|
||||||
|
@ -130,27 +129,25 @@ void FullModelViewer::reloadGear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullModelViewer::updateHeightScaling(float scale) {
|
void FullModelViewer::updateHeightScaling(float scale) {
|
||||||
auto &boneData = *gearView->part().skeleton;
|
auto& boneData = *gearView->part().skeleton;
|
||||||
for (int i = 0; i < boneData.num_bones; i++) {
|
for (int i = 0; i < boneData.num_bones; i++) {
|
||||||
const std::string_view name{boneData.bones[i].name};
|
const std::string_view name{boneData.bones[i].name};
|
||||||
if (name == "n_root") {
|
if (name == "n_root") {
|
||||||
auto racialScaling = physis_cmp_get_racial_scaling_parameters(
|
auto racialScaling =
|
||||||
cmp, gearView->currentRace, gearView->currentSubrace);
|
physis_cmp_get_racial_scaling_parameters(cmp, gearView->currentRace, gearView->currentSubrace);
|
||||||
|
|
||||||
const float minSize = gearView->currentGender == Gender::Male
|
const float minSize =
|
||||||
? racialScaling.male_min_size
|
gearView->currentGender == Gender::Male ? racialScaling.male_min_size : racialScaling.female_min_size;
|
||||||
: racialScaling.female_min_size;
|
const float maxSize =
|
||||||
const float maxSize = gearView->currentGender == Gender::Male
|
gearView->currentGender == Gender::Male ? racialScaling.male_max_size : racialScaling.female_max_size;
|
||||||
? racialScaling.male_max_size
|
|
||||||
: racialScaling.female_max_size;
|
|
||||||
|
|
||||||
const float size = glm::mix(minSize, maxSize, scale);
|
const float size = glm::mix(minSize, maxSize, scale);
|
||||||
|
|
||||||
boneData.bones[i].scale[0] = size;
|
boneData.bones[i].scale[0] = size;
|
||||||
boneData.bones[i].scale[1] = size;
|
boneData.bones[i].scale[1] = size;
|
||||||
boneData.bones[i].scale[2] = size;
|
boneData.bones[i].scale[2] = size;
|
||||||
|
|
||||||
gearView->part().reloadRenderer();
|
gearView->part().reloadRenderer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,25 +155,22 @@ void FullModelViewer::updateHeightScaling(float scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FullModelViewer::updateBustScaling(float scale) {
|
void FullModelViewer::updateBustScaling(float scale) {
|
||||||
auto &boneData = *gearView->part().skeleton;
|
auto& boneData = *gearView->part().skeleton;
|
||||||
for (int i = 0; i < boneData.num_bones; i++) {
|
for (int i = 0; i < boneData.num_bones; i++) {
|
||||||
const std::string_view name{boneData.bones[i].name};
|
const std::string_view name{boneData.bones[i].name};
|
||||||
if (name == "j_mune_l" || name == "j_mune_r") {
|
if (name == "j_mune_l" || name == "j_mune_r") {
|
||||||
auto racialScaling = physis_cmp_get_racial_scaling_parameters(
|
auto racialScaling =
|
||||||
cmp, gearView->currentRace, gearView->currentSubrace);
|
physis_cmp_get_racial_scaling_parameters(cmp, gearView->currentRace, gearView->currentSubrace);
|
||||||
|
|
||||||
const float rangeX = glm::mix(racialScaling.bust_min_x,
|
const float rangeX = glm::mix(racialScaling.bust_min_x, racialScaling.bust_max_x, scale);
|
||||||
racialScaling.bust_max_x, scale);
|
const float rangeY = glm::mix(racialScaling.bust_min_y, racialScaling.bust_max_y, scale);
|
||||||
const float rangeY = glm::mix(racialScaling.bust_min_y,
|
const float rangeZ = glm::mix(racialScaling.bust_min_z, racialScaling.bust_max_z, scale);
|
||||||
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[0] = rangeX;
|
||||||
boneData.bones[i].scale[1] = rangeY;
|
boneData.bones[i].scale[1] = rangeY;
|
||||||
boneData.bones[i].scale[2] = rangeZ;
|
boneData.bones[i].scale[2] = rangeZ;
|
||||||
|
|
||||||
gearView->part().reloadRenderer();
|
gearView->part().reloadRenderer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,46 @@
|
||||||
#include "gearview.h"
|
#include "gearview.h"
|
||||||
#include "magic_enum.hpp"
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
GearView::GearView(GameData *data) : data(data) {
|
GearView::GearView(GameData* data) : data(data) {
|
||||||
mdlPart = new MDLPart(data);
|
mdlPart = new MDLPart(data);
|
||||||
|
|
||||||
reloadRaceDeforms();
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout();
|
|
||||||
layout->addWidget(mdlPart);
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
connect(this, &GearView::gearChanged, this, [=] { reloadModel(); });
|
|
||||||
|
|
||||||
connect(this, &GearView::raceChanged, this, [=] {
|
|
||||||
reloadRaceDeforms();
|
reloadRaceDeforms();
|
||||||
reloadModel();
|
|
||||||
});
|
auto layout = new QVBoxLayout();
|
||||||
connect(this, &GearView::genderChanged, this, [=] {
|
layout->addWidget(mdlPart);
|
||||||
reloadRaceDeforms();
|
setLayout(layout);
|
||||||
reloadModel();
|
|
||||||
});
|
connect(this, &GearView::gearChanged, this, [=] {
|
||||||
connect(this, &GearView::levelOfDetailChanged, this, &GearView::reloadModel);
|
reloadModel();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(this, &GearView::raceChanged, this, [=] {
|
||||||
|
reloadRaceDeforms();
|
||||||
|
reloadModel();
|
||||||
|
});
|
||||||
|
connect(this, &GearView::genderChanged, this, [=] {
|
||||||
|
reloadRaceDeforms();
|
||||||
|
reloadModel();
|
||||||
|
});
|
||||||
|
connect(this, &GearView::levelOfDetailChanged, this, &GearView::reloadModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<Race, Subrace>> GearView::supportedRaces() const {
|
std::vector<std::pair<Race, Subrace>> GearView::supportedRaces() const {
|
||||||
std::vector<std::pair<Race, Subrace>> races;
|
std::vector<std::pair<Race, Subrace>> races;
|
||||||
for (const auto &gear : gears) {
|
for (const auto& gear : gears) {
|
||||||
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
|
for (auto [race, race_name] : magic_enum::enum_entries<Race>()) {
|
||||||
for (auto subrace : physis_get_supported_subraces(race).subraces) {
|
for (auto subrace : physis_get_supported_subraces(race).subraces) {
|
||||||
auto equip_path = physis_build_equipment_path(
|
auto equip_path =
|
||||||
gear.modelInfo.primaryID, race, subrace, currentGender, gear.slot);
|
physis_build_equipment_path(gear.modelInfo.primaryID, race, subrace, currentGender, gear.slot);
|
||||||
|
|
||||||
if (physis_gamedata_exists(data, equip_path))
|
if (physis_gamedata_exists(data, equip_path))
|
||||||
races.emplace_back(race, subrace);
|
races.emplace_back(race, subrace);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return races;
|
return races;
|
||||||
}
|
}
|
||||||
|
@ -46,10 +48,11 @@ std::vector<std::pair<Race, Subrace>> GearView::supportedRaces() const {
|
||||||
std::vector<Gender> GearView::supportedGenders() const {
|
std::vector<Gender> GearView::supportedGenders() const {
|
||||||
std::vector<Gender> genders;
|
std::vector<Gender> genders;
|
||||||
for (const auto& gear : gears) {
|
for (const auto& gear : gears) {
|
||||||
for(auto [gender, gender_name] : magic_enum::enum_entries<Gender>()) {
|
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))
|
if (physis_gamedata_exists(data, equip_path))
|
||||||
genders.push_back(gender);
|
genders.push_back(gender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +64,7 @@ int GearView::lodCount() const {
|
||||||
return maxLod;
|
return maxLod;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GearView::exportModel(const QString &fileName) {
|
void GearView::exportModel(const QString& fileName) {
|
||||||
mdlPart->exportModel(fileName);
|
mdlPart->exportModel(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,8 +90,7 @@ void GearView::setRace(Race race) {
|
||||||
currentRace = race;
|
currentRace = race;
|
||||||
|
|
||||||
auto supportedSubraces = physis_get_supported_subraces(race);
|
auto supportedSubraces = physis_get_supported_subraces(race);
|
||||||
if (supportedSubraces.subraces[0] == currentSubrace ||
|
if (supportedSubraces.subraces[0] == currentSubrace || supportedSubraces.subraces[1] == currentSubrace) {
|
||||||
supportedSubraces.subraces[1] == currentSubrace) {
|
|
||||||
} else {
|
} else {
|
||||||
setSubrace(supportedSubraces.subraces[0]);
|
setSubrace(supportedSubraces.subraces[0]);
|
||||||
}
|
}
|
||||||
|
@ -130,9 +132,9 @@ void GearView::reloadModel() {
|
||||||
|
|
||||||
for (const auto& gear : gears) {
|
for (const auto& gear : gears) {
|
||||||
auto mdl_data = physis_gamedata_extract_file(
|
auto mdl_data = physis_gamedata_extract_file(
|
||||||
data, physis_build_equipment_path(gear.modelInfo.primaryID,
|
data,
|
||||||
currentRace, currentSubrace,
|
physis_build_equipment_path(
|
||||||
currentGender, gear.slot));
|
gear.modelInfo.primaryID, currentRace, currentSubrace, currentGender, gear.slot));
|
||||||
|
|
||||||
// attempt to load the next best race
|
// attempt to load the next best race
|
||||||
// currently hardcoded to hyur midlander
|
// currently hardcoded to hyur midlander
|
||||||
|
@ -140,9 +142,9 @@ void GearView::reloadModel() {
|
||||||
Subrace fallbackSubrace = currentSubrace;
|
Subrace fallbackSubrace = currentSubrace;
|
||||||
if (mdl_data.size == 0) {
|
if (mdl_data.size == 0) {
|
||||||
mdl_data = physis_gamedata_extract_file(
|
mdl_data = physis_gamedata_extract_file(
|
||||||
data, physis_build_equipment_path(
|
data,
|
||||||
gear.modelInfo.primaryID, Race::Hyur,
|
physis_build_equipment_path(
|
||||||
Subrace::Midlander, currentGender, gear.slot));
|
gear.modelInfo.primaryID, Race::Hyur, Subrace::Midlander, currentGender, gear.slot));
|
||||||
fallbackRace = Race::Hyur;
|
fallbackRace = Race::Hyur;
|
||||||
fallbackSubrace = Subrace::Midlander;
|
fallbackSubrace = Subrace::Midlander;
|
||||||
}
|
}
|
||||||
|
@ -152,15 +154,16 @@ void GearView::reloadModel() {
|
||||||
|
|
||||||
std::vector<physis_Material> materials;
|
std::vector<physis_Material> materials;
|
||||||
for (int i = 0; i < mdl.num_material_names; i++) {
|
for (int i = 0; i < mdl.num_material_names; i++) {
|
||||||
const char *material_name = mdl.material_names[i];
|
const char* material_name = mdl.material_names[i];
|
||||||
|
|
||||||
// std::string mtrl_path =
|
// std::string mtrl_path =
|
||||||
// loadedGear.gearInfo->getMtrlPath(201);
|
// loadedGear.gearInfo->getMtrlPath(201);
|
||||||
std::string mtrl_path = fmt::format(
|
std::string mtrl_path = fmt::format(
|
||||||
"chara/equipment/e{gearId:04d}/material/"
|
"chara/equipment/e{gearId:04d}/material/"
|
||||||
"v{gearVersion:04d}{}",
|
"v{gearVersion:04d}{}",
|
||||||
material_name, fmt::arg("gearId", gear.modelInfo.primaryID),
|
material_name,
|
||||||
fmt::arg("gearVersion", gear.modelInfo.gearVersion));
|
fmt::arg("gearId", gear.modelInfo.primaryID),
|
||||||
|
fmt::arg("gearVersion", gear.modelInfo.gearVersion));
|
||||||
|
|
||||||
int bodyCode = 1;
|
int bodyCode = 1;
|
||||||
|
|
||||||
|
@ -169,17 +172,15 @@ void GearView::reloadModel() {
|
||||||
"chara/human/c{raceCode:04d}/obj/body/b{bodyCode:04d}/"
|
"chara/human/c{raceCode:04d}/obj/body/b{bodyCode:04d}/"
|
||||||
"material/v0001{}",
|
"material/v0001{}",
|
||||||
material_name,
|
material_name,
|
||||||
fmt::arg("raceCode",
|
fmt::arg("raceCode", physis_get_race_code(fallbackRace, fallbackSubrace, currentGender)),
|
||||||
physis_get_race_code(fallbackRace, fallbackSubrace,
|
|
||||||
currentGender)),
|
|
||||||
fmt::arg("bodyCode", bodyCode));
|
fmt::arg("bodyCode", bodyCode));
|
||||||
|
|
||||||
if(physis_gamedata_exists(data, mtrl_path.c_str())) {
|
if (physis_gamedata_exists(data, mtrl_path.c_str())) {
|
||||||
auto mat = physis_material_parse(physis_gamedata_extract_file(data, mtrl_path.c_str()));
|
auto mat = physis_material_parse(physis_gamedata_extract_file(data, mtrl_path.c_str()));
|
||||||
materials.push_back(mat);
|
materials.push_back(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(physis_gamedata_exists(data, skinmtrl_path.c_str())) {
|
if (physis_gamedata_exists(data, skinmtrl_path.c_str())) {
|
||||||
auto mat = physis_material_parse(physis_gamedata_extract_file(data, skinmtrl_path.c_str()));
|
auto mat = physis_material_parse(physis_gamedata_extract_file(data, skinmtrl_path.c_str()));
|
||||||
materials.push_back(mat);
|
materials.push_back(mat);
|
||||||
}
|
}
|
||||||
|
@ -195,32 +196,27 @@ void GearView::reloadModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GearView::reloadRaceDeforms() {
|
void GearView::reloadRaceDeforms() {
|
||||||
qDebug() << "Loading race deform matrices for "
|
qDebug() << "Loading race deform matrices for " << magic_enum::enum_name(currentRace).data()
|
||||||
<< magic_enum::enum_name(currentRace).data()
|
<< magic_enum::enum_name(currentSubrace).data() << magic_enum::enum_name(currentGender).data();
|
||||||
<< magic_enum::enum_name(currentSubrace).data()
|
const int raceCode = physis_get_race_code(currentRace, currentSubrace, currentGender);
|
||||||
<< magic_enum::enum_name(currentGender).data();
|
|
||||||
const int raceCode =
|
|
||||||
physis_get_race_code(currentRace, currentSubrace, currentGender);
|
|
||||||
qDebug() << "Race code: " << raceCode;
|
qDebug() << "Race code: " << raceCode;
|
||||||
|
|
||||||
QString skelName =
|
QString skelName = QString{"c%1b0001.skel"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
|
||||||
QString{"c%1b0001.skel"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
|
mdlPart->setSkeleton(physis_skeleton_from_skel(physis_read_file(skelName.toStdString().c_str())));
|
||||||
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
|
// racial deforms don't work on Hyur, not needed? TODO not sure
|
||||||
if (currentRace != Race::Hyur) {
|
if (currentRace != Race::Hyur) {
|
||||||
QString deformName =
|
QString deformName = QString{"c%1_deform.json"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
|
||||||
QString{"c%1_deform.json"}.arg(raceCode, 4, 10, QLatin1Char{'0'});
|
mdlPart->loadRaceDeformMatrices(physis_read_file(deformName.toStdString().c_str()));
|
||||||
mdlPart->loadRaceDeformMatrices(
|
|
||||||
physis_read_file(deformName.toStdString().c_str()));
|
|
||||||
} else {
|
} else {
|
||||||
for (auto &data : mdlPart->boneData) {
|
for (auto& data : mdlPart->boneData) {
|
||||||
data.deformRaceMatrix = glm::mat4(1.0f);
|
data.deformRaceMatrix = glm::mat4(1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MDLPart &GearView::part() const { return *mdlPart; }
|
MDLPart& GearView::part() const {
|
||||||
|
return *mdlPart;
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_gearview.cpp"
|
#include "moc_gearview.cpp"
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QTableWidget>
|
|
||||||
#include <QListWidget>
|
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QTableWidget>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <magic_enum.hpp>
|
|
||||||
#include <QMenuBar>
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <QFileDialog>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <magic_enum.hpp>
|
||||||
#include <physis.hpp>
|
#include <physis.hpp>
|
||||||
|
|
||||||
#include "cmpeditor.h"
|
#include "cmpeditor.h"
|
||||||
|
@ -73,7 +73,7 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
||||||
auto exh = physis_gamedata_read_excel_sheet_header(&data, "Item");
|
auto exh = physis_gamedata_read_excel_sheet_header(&data, "Item");
|
||||||
auto exd = physis_gamedata_read_excel_sheet(&data, "Item", exh, Language::English, 1);
|
auto exd = physis_gamedata_read_excel_sheet(&data, "Item", exh, Language::English, 1);
|
||||||
|
|
||||||
for(int i = 0; i < exd.row_count; i++) {
|
for (int i = 0; i < exd.row_count; i++) {
|
||||||
const auto row = exd.row_data[i];
|
const auto row = exd.row_data[i];
|
||||||
auto primaryModel = row.column_data[47].u_int64._0;
|
auto primaryModel = row.column_data[47].u_int64._0;
|
||||||
auto secondaryModel = row.column_data[48].u_int64._0;
|
auto secondaryModel = row.column_data[48].u_int64._0;
|
||||||
|
@ -90,7 +90,7 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto listWidget = new QListWidget();
|
auto listWidget = new QListWidget();
|
||||||
for(auto gear : gears)
|
for (auto gear : gears)
|
||||||
listWidget->addItem(gear.name.c_str());
|
listWidget->addItem(gear.name.c_str());
|
||||||
|
|
||||||
listWidget->setMaximumWidth(200);
|
listWidget->setMaximumWidth(200);
|
||||||
|
@ -104,8 +104,8 @@ MainWindow::MainWindow(GameData* in_data) : data(*in_data) {
|
||||||
layout->addWidget(gearView);
|
layout->addWidget(gearView);
|
||||||
|
|
||||||
connect(listWidget, &QListWidget::itemClicked, [this](QListWidgetItem* item) {
|
connect(listWidget, &QListWidget::itemClicked, [this](QListWidgetItem* item) {
|
||||||
for(auto& gear : gears) {
|
for (auto& gear : gears) {
|
||||||
if(gear.name == item->text().toStdString()) {
|
if (gear.name == item->text().toStdString()) {
|
||||||
gearView->setGear(gear);
|
gearView->setGear(gear);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,35 +35,35 @@ QuaternionEdit::QuaternionEdit(glm::quat& quat, QWidget* parent) : QWidget(paren
|
||||||
spinBoxes.z->setValue(euler.z);
|
spinBoxes.z->setValue(euler.z);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
spinBoxes.x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
spinBoxes.x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
||||||
auto euler = glm::eulerAngles(this->quat);
|
auto euler = glm::eulerAngles(this->quat);
|
||||||
euler.x = glm::radians(d);
|
euler.x = glm::radians(d);
|
||||||
|
|
||||||
this->quat = glm::quat(euler);
|
this->quat = glm::quat(euler);
|
||||||
|
|
||||||
Q_EMIT onValueChanged();
|
Q_EMIT onValueChanged();
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
spinBoxes.y, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
spinBoxes.y, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
||||||
auto euler = glm::eulerAngles(this->quat);
|
auto euler = glm::eulerAngles(this->quat);
|
||||||
euler.y = glm::radians(d);
|
euler.y = glm::radians(d);
|
||||||
|
|
||||||
this->quat = glm::quat(euler);
|
this->quat = glm::quat(euler);
|
||||||
|
|
||||||
Q_EMIT onValueChanged();
|
Q_EMIT onValueChanged();
|
||||||
});
|
});
|
||||||
connect(
|
connect(
|
||||||
spinBoxes.z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
spinBoxes.z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this](double d) {
|
||||||
auto euler = glm::eulerAngles(this->quat);
|
auto euler = glm::eulerAngles(this->quat);
|
||||||
euler.z = glm::radians(d);
|
euler.z = glm::radians(d);
|
||||||
|
|
||||||
this->quat = glm::quat(euler);
|
this->quat = glm::quat(euler);
|
||||||
|
|
||||||
Q_EMIT onValueChanged();
|
Q_EMIT onValueChanged();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuaternionEdit::setQuat(glm::quat &quat) {
|
void QuaternionEdit::setQuat(glm::quat& quat) {
|
||||||
this->quat = quat;
|
this->quat = quat;
|
||||||
auto euler = glm::eulerAngles(quat);
|
auto euler = glm::eulerAngles(quat);
|
||||||
euler.x = glm::degrees(euler.x);
|
euler.x = glm::degrees(euler.x);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "singlegearview.h"
|
#include "singlegearview.h"
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "magic_enum.hpp"
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
|
@ -17,38 +17,35 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
|
||||||
layout->addLayout(controlLayout);
|
layout->addLayout(controlLayout);
|
||||||
|
|
||||||
raceCombo = new QComboBox();
|
raceCombo = new QComboBox();
|
||||||
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
|
connect(raceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
[this](int index) {
|
if (loadingComboData)
|
||||||
if (loadingComboData)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
setRace((Race)index);
|
setRace((Race)index);
|
||||||
});
|
});
|
||||||
controlLayout->addWidget(raceCombo);
|
controlLayout->addWidget(raceCombo);
|
||||||
|
|
||||||
subraceCombo = new QComboBox();
|
subraceCombo = new QComboBox();
|
||||||
connect(subraceCombo, qOverload<int>(&QComboBox::currentIndexChanged),
|
connect(subraceCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
[this](int index) {
|
if (loadingComboData)
|
||||||
if (loadingComboData)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
setSubrace((Subrace)index);
|
setSubrace((Subrace)index);
|
||||||
});
|
});
|
||||||
controlLayout->addWidget(subraceCombo);
|
controlLayout->addWidget(subraceCombo);
|
||||||
|
|
||||||
genderCombo = new QComboBox();
|
genderCombo = new QComboBox();
|
||||||
connect(genderCombo, qOverload<int>(&QComboBox::currentIndexChanged),
|
connect(genderCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
[this](int index) {
|
if (loadingComboData)
|
||||||
if (loadingComboData)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
setGender((Gender)index);
|
setGender((Gender)index);
|
||||||
});
|
});
|
||||||
controlLayout->addWidget(genderCombo);
|
controlLayout->addWidget(genderCombo);
|
||||||
|
|
||||||
lodCombo = new QComboBox();
|
lodCombo = new QComboBox();
|
||||||
connect(lodCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
connect(lodCombo, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
if(loadingComboData)
|
if (loadingComboData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setLevelOfDetail(index);
|
setLevelOfDetail(index);
|
||||||
|
@ -57,7 +54,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
|
||||||
|
|
||||||
addToFMVButton = new QPushButton("Add to FMV");
|
addToFMVButton = new QPushButton("Add to FMV");
|
||||||
connect(addToFMVButton, &QPushButton::clicked, this, [this](bool) {
|
connect(addToFMVButton, &QPushButton::clicked, this, [this](bool) {
|
||||||
if(currentGear.has_value()) {
|
if (currentGear.has_value()) {
|
||||||
Q_EMIT addToFullModelViewer(*currentGear);
|
Q_EMIT addToFullModelViewer(*currentGear);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -65,9 +62,7 @@ SingleGearView::SingleGearView(GameData* data) : data(data) {
|
||||||
|
|
||||||
exportButton = new QPushButton("Export...");
|
exportButton = new QPushButton("Export...");
|
||||||
connect(exportButton, &QPushButton::clicked, this, [this](bool) {
|
connect(exportButton, &QPushButton::clicked, this, [this](bool) {
|
||||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"),
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Model"), "model.fbx", tr("FBX Files (*.fbx)"));
|
||||||
"model.fbx",
|
|
||||||
tr("FBX Files (*.fbx)"));
|
|
||||||
|
|
||||||
gearView->exportModel(fileName);
|
gearView->exportModel(fileName);
|
||||||
});
|
});
|
||||||
|
@ -93,7 +88,7 @@ void SingleGearView::clear() {
|
||||||
Q_EMIT gearChanged();
|
Q_EMIT gearChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleGearView::setGear(GearInfo &info) {
|
void SingleGearView::setGear(GearInfo& info) {
|
||||||
currentGear = info;
|
currentGear = info;
|
||||||
|
|
||||||
Q_EMIT gearChanged();
|
Q_EMIT gearChanged();
|
||||||
|
@ -101,7 +96,7 @@ void SingleGearView::setGear(GearInfo &info) {
|
||||||
|
|
||||||
void SingleGearView::setRace(Race race) {
|
void SingleGearView::setRace(Race race) {
|
||||||
if (currentRace == race) {
|
if (currentRace == race) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRace = race;
|
currentRace = race;
|
||||||
|
@ -110,7 +105,7 @@ void SingleGearView::setRace(Race race) {
|
||||||
|
|
||||||
void SingleGearView::setSubrace(Subrace subrace) {
|
void SingleGearView::setSubrace(Subrace subrace) {
|
||||||
if (currentSubrace == subrace) {
|
if (currentSubrace == subrace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSubrace = subrace;
|
currentSubrace = subrace;
|
||||||
|
@ -119,7 +114,7 @@ void SingleGearView::setSubrace(Subrace subrace) {
|
||||||
|
|
||||||
void SingleGearView::setGender(Gender gender) {
|
void SingleGearView::setGender(Gender gender) {
|
||||||
if (currentGender == gender) {
|
if (currentGender == gender) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentGender = gender;
|
currentGender = gender;
|
||||||
|
@ -152,17 +147,17 @@ void SingleGearView::reloadGear() {
|
||||||
raceCombo->clear();
|
raceCombo->clear();
|
||||||
subraceCombo->clear();
|
subraceCombo->clear();
|
||||||
for (auto [race, subrace] : gearView->supportedRaces()) {
|
for (auto [race, subrace] : gearView->supportedRaces()) {
|
||||||
raceCombo->addItem(magic_enum::enum_name(race).data());
|
raceCombo->addItem(magic_enum::enum_name(race).data());
|
||||||
subraceCombo->addItem(magic_enum::enum_name(subrace).data());
|
subraceCombo->addItem(magic_enum::enum_name(subrace).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
genderCombo->clear();
|
genderCombo->clear();
|
||||||
for (auto gender : gearView->supportedGenders()) {
|
for (auto gender : gearView->supportedGenders()) {
|
||||||
genderCombo->addItem(magic_enum::enum_name(gender).data());
|
genderCombo->addItem(magic_enum::enum_name(gender).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
lodCombo->clear();
|
lodCombo->clear();
|
||||||
for(int i = 0; i < gearView->lodCount(); i++)
|
for (int i = 0; i < gearView->lodCount(); i++)
|
||||||
lodCombo->addItem(QString::number(i));
|
lodCombo->addItem(QString::number(i));
|
||||||
|
|
||||||
loadingComboData = false;
|
loadingComboData = false;
|
||||||
|
|
|
@ -27,25 +27,34 @@ Vector3Edit::Vector3Edit(glm::vec3& vec, QWidget* parent) : QWidget(parent), vec
|
||||||
spinBoxes.y->setValue(vec.y);
|
spinBoxes.y->setValue(vec.y);
|
||||||
spinBoxes.z->setValue(vec.z);
|
spinBoxes.z->setValue(vec.z);
|
||||||
|
|
||||||
connect(spinBoxes.x, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this, &vec](double d) {
|
connect(
|
||||||
vec.x = d;
|
spinBoxes.x,
|
||||||
emit onValueChanged();
|
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.x = d;
|
||||||
vec.y = d;
|
emit onValueChanged();
|
||||||
emit onValueChanged();
|
});
|
||||||
});
|
connect(
|
||||||
connect(spinBoxes.z, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [this, &vec](double d) {
|
spinBoxes.y,
|
||||||
vec.z = d;
|
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
|
||||||
emit onValueChanged();
|
[this, &vec](double d) {
|
||||||
});
|
vec.y = d;
|
||||||
|
emit onValueChanged();
|
||||||
|
});
|
||||||
|
connect(
|
||||||
|
spinBoxes.z,
|
||||||
|
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
|
||||||
|
[this, &vec](double d) {
|
||||||
|
vec.z = d;
|
||||||
|
emit onValueChanged();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3Edit::~Vector3Edit() {
|
Vector3Edit::~Vector3Edit() {
|
||||||
updateTimer->stop();
|
updateTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3Edit::setVector(glm::vec3 &vec) {
|
void Vector3Edit::setVector(glm::vec3& vec) {
|
||||||
this->vec = vec;
|
this->vec = vec;
|
||||||
spinBoxes.x->setValue(vec.x);
|
spinBoxes.x->setValue(vec.x);
|
||||||
spinBoxes.y->setValue(vec.y);
|
spinBoxes.y->setValue(vec.y);
|
||||||
|
|
Loading…
Add table
Reference in a new issue