From e7249db0896833b5965d4a421b6739ee8bc0282c Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Fri, 2 Nov 2018 13:43:01 +0800 Subject: [PATCH] Add translation parameter for pose editor --- src/genericposer.cpp | 13 ++++++++++ src/genericrigger.cpp | 3 +++ src/jointnodetree.cpp | 11 +++++++++ src/jointnodetree.h | 2 ++ src/poseeditwidget.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++ src/rigger.h | 3 ++- src/tetrapodposer.cpp | 13 ++++++++++ src/tetrapodrigger.cpp | 3 +++ 8 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/genericposer.cpp b/src/genericposer.cpp index e7c3658d..2942136f 100644 --- a/src/genericposer.cpp +++ b/src/genericposer.cpp @@ -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(); diff --git a/src/genericrigger.cpp b/src/genericrigger.cpp index 2822b28a..4bff8e80 100644 --- a/src/genericrigger.cpp +++ b/src/genericrigger.cpp @@ -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; diff --git a/src/jointnodetree.cpp b/src/jointnodetree.cpp index e4410491..eea19dd1 100644 --- a/src/jointnodetree.cpp +++ b/src/jointnodetree.cpp @@ -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; diff --git a/src/jointnodetree.h b/src/jointnodetree.h index 224e0b94..689017a1 100644 --- a/src/jointnodetree.h +++ b/src/jointnodetree.h @@ -23,6 +23,8 @@ public: const std::vector &nodes() const; JointNodeTree(const std::vector *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); diff --git a/src/poseeditwidget.cpp b/src/poseeditwidget.cpp index e3241bec..1b8ac0be 100644 --- a/src/poseeditwidget.cpp +++ b/src/poseeditwidget.cpp @@ -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); diff --git a/src/rigger.h b/src/rigger.h index 678def28..183b9258 100644 --- a/src/rigger.h +++ b/src/rigger.h @@ -15,7 +15,8 @@ enum class RiggerButtonParameterType { None = 0, PitchYawRoll, - Intersection + Intersection, + Translation }; class RiggerMark diff --git a/src/tetrapodposer.cpp b/src/tetrapodposer.cpp index df5369e2..d9203515 100644 --- a/src/tetrapodposer.cpp +++ b/src/tetrapodposer.cpp @@ -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(); diff --git a/src/tetrapodrigger.cpp b/src/tetrapodrigger.cpp index f84eac62..27e61bab 100644 --- a/src/tetrapodrigger.cpp +++ b/src/tetrapodrigger.cpp @@ -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());