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:
parent
b1e5728f8f
commit
0c9cb2b0cf
5 changed files with 96 additions and 4 deletions
|
@ -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;
|
||||||
};
|
};
|
|
@ -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"));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
@ -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;
|
||||||
};
|
};
|
Loading…
Add table
Reference in a new issue