1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-27 14:17:45 +00:00

Attempt to display racial transforms in the bone editor

Not sure if it 100% works yet
This commit is contained in:
Joshua Goins 2024-04-30 15:56:26 -04:00
parent b1e5728f8f
commit 0c9cb2b0cf
5 changed files with 96 additions and 4 deletions

View file

@ -6,6 +6,7 @@
#include <QGroupBox> #include <QGroupBox>
#include <QMainWindow> #include <QMainWindow>
#include "boneeditor.h"
#include "gearview.h" #include "gearview.h"
struct GameData; struct GameData;
@ -39,6 +40,7 @@ private:
void updateBustScaling(float scale); void updateBustScaling(float scale);
void updateCharacterParameters(); void updateCharacterParameters();
void updateSupportedSubraces(); void updateSupportedSubraces();
void updateRaceData();
QGroupBox *addFaceGroup(); QGroupBox *addFaceGroup();
QGroupBox *addHairGroup(); QGroupBox *addHairGroup();
@ -54,6 +56,8 @@ private:
GameData *data = nullptr; GameData *data = nullptr;
physis_CMP cmp{}; physis_CMP cmp{};
BoneEditor *m_boneEditor;
float heightScale = 0.5f; float heightScale = 0.5f;
float bustScale = 1.0f; float bustScale = 1.0f;
}; };

View file

@ -55,9 +55,11 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
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, cache); gearView = new GearView(data, cache);
updateCharacterParameters();
connect(gearView, &GearView::modelReloaded, this, &FullModelViewer::updateCharacterParameters); connect(gearView, &GearView::modelReloaded, this, &FullModelViewer::updateCharacterParameters);
connect(gearView, &GearView::raceChanged, this, &FullModelViewer::updateRaceData);
connect(gearView, &GearView::subraceChanged, this, &FullModelViewer::updateRaceData);
connect(gearView, &GearView::genderChanged, this, &FullModelViewer::updateRaceData);
auto viewportLayout = new QHBoxLayout(); auto viewportLayout = new QHBoxLayout();
viewportLayout->setContentsMargins(0, 0, 0, 0); viewportLayout->setContentsMargins(0, 0, 0, 0);
@ -91,8 +93,10 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
characterEditorLayout->addWidget(addEarGroup()); characterEditorLayout->addWidget(addEarGroup());
characterEditorLayout->addWidget(addTailGroup()); characterEditorLayout->addWidget(addTailGroup());
m_boneEditor = new BoneEditor(gearView);
auto tabWidget = new QTabWidget(); auto tabWidget = new QTabWidget();
tabWidget->addTab(new BoneEditor(gearView), i18nc("@title:tab", "Bone Editor")); tabWidget->addTab(m_boneEditor, i18nc("@title:tab", "Bone Editor"));
tabWidget->addTab(characterEditorWidget, i18nc("@title:tab", "Character Editor")); tabWidget->addTab(characterEditorWidget, i18nc("@title:tab", "Character Editor"));
viewportLayout->addWidget(tabWidget); viewportLayout->addWidget(tabWidget);
@ -138,6 +142,8 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
tabWidget->setEnabled(!loading); tabWidget->setEnabled(!loading);
}); });
updateCharacterParameters();
updateRaceData();
reloadGear(); reloadGear();
} }
@ -292,6 +298,13 @@ void FullModelViewer::updateSupportedSubraces()
} }
} }
void FullModelViewer::updateRaceData()
{
m_boneEditor->load_pbd(gearView->part().pbd,
physis_get_race_code(Race::Hyur, Subrace::Midlander, gearView->currentGender),
physis_get_race_code(gearView->currentRace, gearView->currentSubrace, gearView->currentGender));
}
QGroupBox *FullModelViewer::addFaceGroup() QGroupBox *FullModelViewer::addFaceGroup()
{ {
auto faceGroup = new QGroupBox(i18nc("@title:group", "Face")); auto faceGroup = new QGroupBox(i18nc("@title:group", "Face"));

View file

@ -49,6 +49,8 @@ public:
int numModels() const; int numModels() const;
physis_PBD pbd{};
Q_SIGNALS: Q_SIGNALS:
void modelChanged(); void modelChanged();
void skeletonChanged(); void skeletonChanged();
@ -91,7 +93,6 @@ private:
GameData *data = nullptr; GameData *data = nullptr;
FileCache &cache; FileCache &cache;
physis_PBD pbd{};
std::vector<DrawObject> models; std::vector<DrawObject> models;

View file

@ -8,6 +8,8 @@
#include <QGroupBox> #include <QGroupBox>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/gtx/matrix_major_storage.hpp>
#include "quaternionedit.h" #include "quaternionedit.h"
#include "vec3edit.h" #include "vec3edit.h"
@ -41,7 +43,7 @@ SklbPart::SklbPart(QWidget *parent)
layout->addWidget(boneListWidget); layout->addWidget(boneListWidget);
auto transformLayout = new QVBoxLayout(); transformLayout = new QVBoxLayout();
layout->addLayout(transformLayout); layout->addLayout(transformLayout);
auto transformGroup = new QGroupBox(i18nc("@title:group", "Bone Transform")); auto transformGroup = new QGroupBox(i18nc("@title:group", "Bone Transform"));
@ -50,6 +52,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroup->setLayout(transformGroupLayout); transformGroup->setLayout(transformGroupLayout);
posEdit = new Vector3Edit(currentPosition); posEdit = new Vector3Edit(currentPosition);
posEdit->setEnabled(false);
connect(posEdit, &Vector3Edit::onValueChanged, [this] { connect(posEdit, &Vector3Edit::onValueChanged, [this] {
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition), sizeof(float) * 3); memcpy(currentEditedBone->position, glm::value_ptr(currentPosition), sizeof(float) * 3);
Q_EMIT valueChanged(); Q_EMIT valueChanged();
@ -57,6 +60,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroupLayout->addRow(i18nc("@label:spinbox", "Position"), posEdit); transformGroupLayout->addRow(i18nc("@label:spinbox", "Position"), posEdit);
rotationEdit = new QuaternionEdit(currentRotation); rotationEdit = new QuaternionEdit(currentRotation);
rotationEdit->setEnabled(false);
connect(rotationEdit, &QuaternionEdit::onValueChanged, [this] { connect(rotationEdit, &QuaternionEdit::onValueChanged, [this] {
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation), sizeof(float) * 4); memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation), sizeof(float) * 4);
Q_EMIT valueChanged(); Q_EMIT valueChanged();
@ -64,6 +68,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroupLayout->addRow(i18nc("@label:spinbox", "Rotation"), rotationEdit); transformGroupLayout->addRow(i18nc("@label:spinbox", "Rotation"), rotationEdit);
scaleEdit = new Vector3Edit(currentScale); scaleEdit = new Vector3Edit(currentScale);
scaleEdit->setEnabled(false);
connect(scaleEdit, &Vector3Edit::onValueChanged, [this] { connect(scaleEdit, &Vector3Edit::onValueChanged, [this] {
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale), sizeof(float) * 3); memcpy(currentEditedBone->scale, glm::value_ptr(currentScale), sizeof(float) * 3);
Q_EMIT valueChanged(); Q_EMIT valueChanged();
@ -82,9 +87,46 @@ void SklbPart::treeItemClicked(QTreeWidgetItem *item, int column)
currentScale = glm::make_vec3(skeleton.bones[i].scale); currentScale = glm::make_vec3(skeleton.bones[i].scale);
currentEditedBone = &skeleton.bones[i]; currentEditedBone = &skeleton.bones[i];
posEdit->setEnabled(true);
posEdit->setVector(currentPosition); posEdit->setVector(currentPosition);
rotationEdit->setEnabled(true);
rotationEdit->setQuat(currentRotation); rotationEdit->setQuat(currentRotation);
scaleEdit->setEnabled(true);
scaleEdit->setVector(currentScale); scaleEdit->setVector(currentScale);
if (racePosEdit != nullptr && raceRotationEdit != nullptr && raceScaleEdit != nullptr) {
for (int j = 0; j < m_matrices.num_bones; j++) {
if (std::string_view{m_matrices.bones[j].name} == std::string_view{skeleton.bones[i].name}) {
auto deformBone = glm::rowMajor4(glm::vec4{m_matrices.bones[j].deform[0],
m_matrices.bones[j].deform[1],
m_matrices.bones[j].deform[2],
m_matrices.bones[j].deform[3]},
glm::vec4{m_matrices.bones[j].deform[4],
m_matrices.bones[j].deform[5],
m_matrices.bones[j].deform[6],
m_matrices.bones[j].deform[7]},
glm::vec4{m_matrices.bones[j].deform[8],
m_matrices.bones[j].deform[9],
m_matrices.bones[j].deform[10],
m_matrices.bones[j].deform[11]},
glm::vec4{0.0f, 0.0f, 0.0f, 1.0f});
;
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(deformBone, scale, rotation, translation, skew, perspective);
racePosEdit->setVector(translation);
raceRotationEdit->setQuat(rotation);
raceScaleEdit->setVector(scale);
}
}
}
} }
} }
} }
@ -101,4 +143,28 @@ void SklbPart::load(physis_Skeleton file)
skeleton = file; skeleton = file;
} }
void SklbPart::load_pbd(physis_PBD deformer, int from_body_id, int to_body_id)
{
if (racePosEdit == nullptr && raceRotationEdit == nullptr && raceScaleEdit == nullptr) {
auto raceTransformGroup = new QGroupBox(i18nc("@title:group", "Race Transform"));
transformLayout->addWidget(raceTransformGroup);
auto raceTransformGroupLayout = new QFormLayout();
raceTransformGroup->setLayout(raceTransformGroupLayout);
racePosEdit = new Vector3Edit(currentPosition);
racePosEdit->setEnabled(false);
raceTransformGroupLayout->addRow(i18nc("@label:spinbox", "Position"), racePosEdit);
raceRotationEdit = new QuaternionEdit(currentRotation);
raceRotationEdit->setEnabled(false);
raceTransformGroupLayout->addRow(i18nc("@label:spinbox", "Rotation"), raceRotationEdit);
raceScaleEdit = new Vector3Edit(currentScale);
raceScaleEdit->setEnabled(false);
raceTransformGroupLayout->addRow(i18nc("@label:spinbox", "Scale"), raceScaleEdit);
}
m_matrices = physis_pbd_get_deform_matrix(deformer, from_body_id, to_body_id);
}
#include "moc_sklbpart.cpp" #include "moc_sklbpart.cpp"

View file

@ -6,6 +6,7 @@
#include <QSpinBox> #include <QSpinBox>
#include <QTreeWidget> #include <QTreeWidget>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
#include <QVBoxLayout>
#include <QWidget> #include <QWidget>
#include <glm/detail/type_quat.hpp> #include <glm/detail/type_quat.hpp>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -23,6 +24,7 @@ public:
void clear(); void clear();
void load(physis_Skeleton file); void load(physis_Skeleton file);
void load_pbd(physis_PBD deformer, int from_body_id, int to_body_id);
Q_SIGNALS: Q_SIGNALS:
void valueChanged(); void valueChanged();
@ -42,4 +44,10 @@ private:
QuaternionEdit *rotationEdit = nullptr; QuaternionEdit *rotationEdit = nullptr;
Vector3Edit *scaleEdit = nullptr; Vector3Edit *scaleEdit = nullptr;
physis_Skeleton skeleton; physis_Skeleton skeleton;
physis_PreBoneDeformMatrices m_matrices;
Vector3Edit *racePosEdit = nullptr;
QuaternionEdit *raceRotationEdit = nullptr;
Vector3Edit *raceScaleEdit = nullptr;
QVBoxLayout *transformLayout = nullptr;
}; };