1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-27 06:07: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 <QMainWindow>
#include "boneeditor.h"
#include "gearview.h"
struct GameData;
@ -39,6 +40,7 @@ private:
void updateBustScaling(float scale);
void updateCharacterParameters();
void updateSupportedSubraces();
void updateRaceData();
QGroupBox *addFaceGroup();
QGroupBox *addHairGroup();
@ -54,6 +56,8 @@ private:
GameData *data = nullptr;
physis_CMP cmp{};
BoneEditor *m_boneEditor;
float heightScale = 0.5f;
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"));
gearView = new GearView(data, cache);
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();
viewportLayout->setContentsMargins(0, 0, 0, 0);
@ -91,8 +93,10 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
characterEditorLayout->addWidget(addEarGroup());
characterEditorLayout->addWidget(addTailGroup());
m_boneEditor = new BoneEditor(gearView);
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"));
viewportLayout->addWidget(tabWidget);
@ -138,6 +142,8 @@ FullModelViewer::FullModelViewer(GameData *data, FileCache &cache, QWidget *pare
tabWidget->setEnabled(!loading);
});
updateCharacterParameters();
updateRaceData();
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()
{
auto faceGroup = new QGroupBox(i18nc("@title:group", "Face"));

View file

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

View file

@ -8,6 +8,8 @@
#include <QGroupBox>
#include <QHBoxLayout>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/matrix_decompose.hpp>
#include <glm/gtx/matrix_major_storage.hpp>
#include "quaternionedit.h"
#include "vec3edit.h"
@ -41,7 +43,7 @@ SklbPart::SklbPart(QWidget *parent)
layout->addWidget(boneListWidget);
auto transformLayout = new QVBoxLayout();
transformLayout = new QVBoxLayout();
layout->addLayout(transformLayout);
auto transformGroup = new QGroupBox(i18nc("@title:group", "Bone Transform"));
@ -50,6 +52,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroup->setLayout(transformGroupLayout);
posEdit = new Vector3Edit(currentPosition);
posEdit->setEnabled(false);
connect(posEdit, &Vector3Edit::onValueChanged, [this] {
memcpy(currentEditedBone->position, glm::value_ptr(currentPosition), sizeof(float) * 3);
Q_EMIT valueChanged();
@ -57,6 +60,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroupLayout->addRow(i18nc("@label:spinbox", "Position"), posEdit);
rotationEdit = new QuaternionEdit(currentRotation);
rotationEdit->setEnabled(false);
connect(rotationEdit, &QuaternionEdit::onValueChanged, [this] {
memcpy(currentEditedBone->rotation, glm::value_ptr(currentRotation), sizeof(float) * 4);
Q_EMIT valueChanged();
@ -64,6 +68,7 @@ SklbPart::SklbPart(QWidget *parent)
transformGroupLayout->addRow(i18nc("@label:spinbox", "Rotation"), rotationEdit);
scaleEdit = new Vector3Edit(currentScale);
scaleEdit->setEnabled(false);
connect(scaleEdit, &Vector3Edit::onValueChanged, [this] {
memcpy(currentEditedBone->scale, glm::value_ptr(currentScale), sizeof(float) * 3);
Q_EMIT valueChanged();
@ -82,9 +87,46 @@ void SklbPart::treeItemClicked(QTreeWidgetItem *item, int column)
currentScale = glm::make_vec3(skeleton.bones[i].scale);
currentEditedBone = &skeleton.bones[i];
posEdit->setEnabled(true);
posEdit->setVector(currentPosition);
rotationEdit->setEnabled(true);
rotationEdit->setQuat(currentRotation);
scaleEdit->setEnabled(true);
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;
}
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"

View file

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