Add translation parameter for pose editor
parent
0d45d65b98
commit
e7249db089
|
@ -38,6 +38,19 @@ void GenericPoser::commit()
|
|||
m_jointNodeTree.updateRotation(boneIndex, rotation);
|
||||
continue;
|
||||
}
|
||||
auto findXResult = item.second.find("x");
|
||||
auto findYResult = item.second.find("y");
|
||||
auto findZResult = item.second.find("z");
|
||||
if (findXResult != item.second.end() ||
|
||||
findYResult != item.second.end() ||
|
||||
findZResult != item.second.end()) {
|
||||
float x = valueOfKeyInMapOrEmpty(item.second, "x").toFloat();
|
||||
float y = valueOfKeyInMapOrEmpty(item.second, "y").toFloat();
|
||||
float z = valueOfKeyInMapOrEmpty(item.second, "z").toFloat();
|
||||
QVector3D translation = {x, y, z};
|
||||
m_jointNodeTree.addTranslation(boneIndex, translation);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Poser::commit();
|
||||
|
|
|
@ -304,6 +304,9 @@ bool GenericRigger::rig()
|
|||
bodyBone.index = m_resultBones.size() - 1;
|
||||
bodyBone.name = "Body";
|
||||
bodyBone.headPosition = QVector3D(0, 0, 0);
|
||||
bodyBone.hasButton = true;
|
||||
bodyBone.button = {spineNodes.size(), 0};
|
||||
bodyBone.buttonParameterType = RiggerButtonParameterType::Translation;
|
||||
boneIndexMap[bodyBone.name] = bodyBone.index;
|
||||
|
||||
auto remainingSpineVerticies = bodyVerticies;
|
||||
|
|
|
@ -11,6 +11,16 @@ void JointNodeTree::updateRotation(int index, QQuaternion rotation)
|
|||
m_boneNodes[index].rotation = rotation;
|
||||
}
|
||||
|
||||
void JointNodeTree::updateTranslation(int index, QVector3D translation)
|
||||
{
|
||||
m_boneNodes[index].translation = translation;
|
||||
}
|
||||
|
||||
void JointNodeTree::addTranslation(int index, QVector3D translation)
|
||||
{
|
||||
m_boneNodes[index].translation += translation;
|
||||
}
|
||||
|
||||
void JointNodeTree::reset()
|
||||
{
|
||||
for (auto &node: m_boneNodes) {
|
||||
|
@ -80,6 +90,7 @@ JointNodeTree JointNodeTree::slerp(const JointNodeTree &first, const JointNodeTr
|
|||
for (decltype(first.nodes().size()) i = 0; i < first.nodes().size() && i < second.nodes().size(); i++) {
|
||||
slerpResult.updateRotation(i,
|
||||
quaternionOvershootSlerp(first.nodes()[i].rotation, second.nodes()[i].rotation, t));
|
||||
slerpResult.updateTranslation(i, (first.nodes()[i].translation * (1.0 - t) + second.nodes()[i].translation * t));
|
||||
}
|
||||
slerpResult.recalculateTransformMatrices();
|
||||
return slerpResult;
|
||||
|
|
|
@ -23,6 +23,8 @@ public:
|
|||
const std::vector<JointNode> &nodes() const;
|
||||
JointNodeTree(const std::vector<RiggerBone> *resultRigBones);
|
||||
void updateRotation(int index, QQuaternion rotation);
|
||||
void updateTranslation(int index, QVector3D translation);
|
||||
void addTranslation(int index, QVector3D translation);
|
||||
void reset();
|
||||
void recalculateTransformMatrices();
|
||||
static JointNodeTree slerp(const JointNodeTree &first, const JointNodeTree &second, float t);
|
||||
|
|
|
@ -294,6 +294,60 @@ void PoseEditWidget::showPopupAngleDialog(QString boneName, PopupWidgetType popu
|
|||
intersectionLayout->addWidget(intersectionEraser);
|
||||
intersectionLayout->addWidget(intersectionWidget);
|
||||
layout->addLayout(intersectionLayout);
|
||||
} else if (PopupWidgetType::Translation == popupWidgetType) {
|
||||
FloatNumberWidget *xWidget = new FloatNumberWidget;
|
||||
xWidget->setItemName(tr("X"));
|
||||
xWidget->setRange(-1, 1);
|
||||
xWidget->setValue(valueOfKeyInMapOrEmpty(m_parameters[boneName], "x").toFloat());
|
||||
connect(xWidget, &FloatNumberWidget::valueChanged, this, [=](float value) {
|
||||
m_parameters[boneName]["x"] = QString::number(value);
|
||||
emit parametersAdjusted();
|
||||
});
|
||||
QPushButton *xEraser = new QPushButton(QChar(fa::eraser));
|
||||
Theme::initAwesomeMiniButton(xEraser);
|
||||
connect(xEraser, &QPushButton::clicked, this, [=]() {
|
||||
xWidget->setValue(0.0);
|
||||
});
|
||||
QHBoxLayout *xLayout = new QHBoxLayout;
|
||||
xLayout->addWidget(xEraser);
|
||||
xLayout->addWidget(xWidget);
|
||||
layout->addLayout(xLayout);
|
||||
|
||||
FloatNumberWidget *yWidget = new FloatNumberWidget;
|
||||
yWidget->setItemName(tr("Y"));
|
||||
yWidget->setRange(-1, 1);
|
||||
yWidget->setValue(valueOfKeyInMapOrEmpty(m_parameters[boneName], "y").toFloat());
|
||||
connect(yWidget, &FloatNumberWidget::valueChanged, this, [=](float value) {
|
||||
m_parameters[boneName]["y"] = QString::number(value);
|
||||
emit parametersAdjusted();
|
||||
});
|
||||
QPushButton *yEraser = new QPushButton(QChar(fa::eraser));
|
||||
Theme::initAwesomeMiniButton(yEraser);
|
||||
connect(yEraser, &QPushButton::clicked, this, [=]() {
|
||||
yWidget->setValue(0.0);
|
||||
});
|
||||
QHBoxLayout *yLayout = new QHBoxLayout;
|
||||
yLayout->addWidget(yEraser);
|
||||
yLayout->addWidget(yWidget);
|
||||
layout->addLayout(yLayout);
|
||||
|
||||
FloatNumberWidget *zWidget = new FloatNumberWidget;
|
||||
zWidget->setItemName(tr("Z"));
|
||||
zWidget->setRange(-1, 1);
|
||||
zWidget->setValue(valueOfKeyInMapOrEmpty(m_parameters[boneName], "z").toFloat());
|
||||
connect(zWidget, &FloatNumberWidget::valueChanged, this, [=](float value) {
|
||||
m_parameters[boneName]["z"] = QString::number(value);
|
||||
emit parametersAdjusted();
|
||||
});
|
||||
QPushButton *zEraser = new QPushButton(QChar(fa::eraser));
|
||||
Theme::initAwesomeMiniButton(zEraser);
|
||||
connect(zEraser, &QPushButton::clicked, this, [=]() {
|
||||
zWidget->setValue(0.0);
|
||||
});
|
||||
QHBoxLayout *zLayout = new QHBoxLayout;
|
||||
zLayout->addWidget(zEraser);
|
||||
zLayout->addWidget(zWidget);
|
||||
layout->addLayout(zLayout);
|
||||
}
|
||||
|
||||
popup->setLayout(layout);
|
||||
|
|
|
@ -15,7 +15,8 @@ enum class RiggerButtonParameterType
|
|||
{
|
||||
None = 0,
|
||||
PitchYawRoll,
|
||||
Intersection
|
||||
Intersection,
|
||||
Translation
|
||||
};
|
||||
|
||||
class RiggerMark
|
||||
|
|
|
@ -65,6 +65,19 @@ void TetrapodPoser::commit()
|
|||
}
|
||||
continue;
|
||||
}
|
||||
auto findXResult = item.second.find("x");
|
||||
auto findYResult = item.second.find("y");
|
||||
auto findZResult = item.second.find("z");
|
||||
if (findXResult != item.second.end() ||
|
||||
findYResult != item.second.end() ||
|
||||
findZResult != item.second.end()) {
|
||||
float x = valueOfKeyInMapOrEmpty(item.second, "x").toFloat();
|
||||
float y = valueOfKeyInMapOrEmpty(item.second, "y").toFloat();
|
||||
float z = valueOfKeyInMapOrEmpty(item.second, "z").toFloat();
|
||||
QVector3D translation = {x, y, z};
|
||||
m_jointNodeTree.addTranslation(boneIndex, translation);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Poser::commit();
|
||||
|
|
|
@ -374,6 +374,9 @@ bool TetrapodRigger::rig()
|
|||
bodyBone.name = "Body";
|
||||
bodyBone.headPosition = QVector3D(0, 0, 0);
|
||||
bodyBone.tailPosition = bonesOrigin;
|
||||
bodyBone.hasButton = true;
|
||||
bodyBone.button = {7, 1};
|
||||
bodyBone.buttonParameterType = RiggerButtonParameterType::Translation;
|
||||
boneIndexMap[bodyBone.name] = bodyBone.index;
|
||||
|
||||
m_resultBones.push_back(RiggerBone());
|
||||
|
|
Loading…
Reference in New Issue