From 9475e9e0aca53a9aad13bd302514460d68662478 Mon Sep 17 00:00:00 2001 From: Jeremy HU Date: Tue, 29 Nov 2022 21:32:19 +1100 Subject: [PATCH] Implement bone joints picking --- application/sources/bone_manage_widget.cc | 4 +- application/sources/bone_property_widget.cc | 4 +- application/sources/bone_property_widget.h | 2 +- application/sources/document.cc | 46 +++++++++++++++++++ application/sources/document.h | 7 +++ application/sources/document_window.cc | 2 + .../sources/skeleton_graphics_widget.cc | 1 - 7 files changed, 61 insertions(+), 5 deletions(-) diff --git a/application/sources/bone_manage_widget.cc b/application/sources/bone_manage_widget.cc index db88f327..30f389c7 100644 --- a/application/sources/bone_manage_widget.cc +++ b/application/sources/bone_manage_widget.cc @@ -77,10 +77,10 @@ void BoneManageWidget::showSelectedBoneProperties() m_propertyMenu = std::make_unique(this->parentWidget()); - connect(propertyWidget, &BonePropertyWidget::pickBoneJoints, this, [this]() { + connect(propertyWidget, &BonePropertyWidget::pickBoneJoints, this, [this](const dust3d::Uuid& boneId, size_t joints) { if (nullptr == this->m_propertyMenu) return; - this->m_document->setEditMode(Document::EditMode::Pick); + this->m_document->startBoneJointsPicking(boneId, joints); this->m_propertyMenu->close(); }); diff --git a/application/sources/bone_property_widget.cc b/application/sources/bone_property_widget.cc index e898a0d4..c1eeaa24 100644 --- a/application/sources/bone_property_widget.cc +++ b/application/sources/bone_property_widget.cc @@ -41,7 +41,9 @@ BonePropertyWidget::BonePropertyWidget(Document* document, nodePicker->setToolTip(tr("Click node one by one on canvas as joints in order")); Theme::initIconButton(nodePicker); - connect(nodePicker, &QPushButton::clicked, this, &BonePropertyWidget::pickBoneJoints); + connect(nodePicker, &QPushButton::clicked, this, [this]() { + emit this->pickBoneJoints(this->m_boneId, (size_t)this->m_jointsWidget->value()); + }); QHBoxLayout* jointsLayout = new QHBoxLayout; jointsLayout->addWidget(new QLabel(tr("Joints"))); diff --git a/application/sources/bone_property_widget.h b/application/sources/bone_property_widget.h index a8104eaa..57877697 100644 --- a/application/sources/bone_property_widget.h +++ b/application/sources/bone_property_widget.h @@ -13,7 +13,7 @@ class BonePropertyWidget : public QWidget { signals: void renameBone(const dust3d::Uuid& boneId, const QString& name); void groupOperationAdded(); - void pickBoneJoints(); + void pickBoneJoints(const dust3d::Uuid& boneId, size_t joints); public: BonePropertyWidget(Document* document, diff --git a/application/sources/document.cc b/application/sources/document.cc index b84b26e9..811ba1db 100644 --- a/application/sources/document.cc +++ b/application/sources/document.cc @@ -1562,6 +1562,9 @@ void Document::setEditMode(Document::EditMode mode) if (editMode == mode) return; + if (EditMode::Pick == editMode) + resetCurrentBone(); + editMode = mode; emit editModeChanged(); } @@ -2925,3 +2928,46 @@ const Document::Bone* Document::findBone(const dust3d::Uuid& boneId) const return nullptr; return &boneIt->second; } + +void Document::stopBoneJointsPicking() +{ + if (EditMode::Pick != editMode) + return; + setEditMode(EditMode::Select); +} + +void Document::startBoneJointsPicking(const dust3d::Uuid& boneId, size_t boneJoints) +{ + stopBoneJointsPicking(); + + m_currentBondId = boneId; + m_currentBoneJoints = boneJoints; + + setEditMode(EditMode::Pick); +} + +void Document::resetCurrentBone() +{ + m_currentBondId = dust3d::Uuid(); + m_currentBoneJoints = 0; + m_currentBoneJointNodes.clear(); +} + +void Document::pickBoneNode(const dust3d::Uuid& nodeId) +{ + if (m_currentBondId.isNull()) + return; + + for (const auto& it : m_currentBoneJointNodes) { + if (it == nodeId) + return; + } + + m_currentBoneJointNodes.push_back(nodeId); + if (m_currentBoneJointNodes.size() < m_currentBoneJoints) + return; + + // TODO: Apply bone joints + + stopBoneJointsPicking(); +} diff --git a/application/sources/document.h b/application/sources/document.h index 7d22120f..08807be9 100644 --- a/application/sources/document.h +++ b/application/sources/document.h @@ -519,6 +519,9 @@ public slots: void removeBone(const dust3d::Uuid& boneId); void setBoneAttachment(const dust3d::Uuid& boneId, const dust3d::Uuid& toBoneId, int toBoneJointIndex); void renameBone(const dust3d::Uuid& boneId, const QString& name); + void startBoneJointsPicking(const dust3d::Uuid& boneId, size_t boneJoints); + void stopBoneJointsPicking(); + void pickBoneNode(const dust3d::Uuid& nodeId); private: void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile); @@ -533,6 +536,7 @@ private: void removeComponentRecursively(dust3d::Uuid componentId); void updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId); dust3d::Uuid createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId); + void resetCurrentBone(); bool m_isResultMeshObsolete = false; MeshGenerator* m_meshGenerator = nullptr; @@ -557,6 +561,9 @@ private: float m_originZ = 0; dust3d::Uuid m_currentCanvasComponentId; bool m_allPositionRelatedLocksEnabled = true; + dust3d::Uuid m_currentBondId; + size_t m_currentBoneJoints = 0; + std::vector m_currentBoneJointNodes; private: static unsigned long m_maxSnapshot; diff --git a/application/sources/document_window.cc b/application/sources/document_window.cc index 23172ba4..8ae28266 100644 --- a/application/sources/document_window.cc +++ b/application/sources/document_window.cc @@ -574,6 +574,8 @@ DocumentWindow::DocumentWindow() connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::addNodesToBone, m_document, &Document::addNodesToBone); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::removeNodesFromBone, m_document, &Document::removeNodesFromBone); + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::nodePicked, m_document, &Document::pickBoneNode); + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setXlockState, m_document, &Document::setXlockState); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setYlockState, m_document, &Document::setYlockState); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setZlockState, m_document, &Document::setZlockState); diff --git a/application/sources/skeleton_graphics_widget.cc b/application/sources/skeleton_graphics_widget.cc index fb051463..a529ca68 100644 --- a/application/sources/skeleton_graphics_widget.cc +++ b/application/sources/skeleton_graphics_widget.cc @@ -1487,7 +1487,6 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event) } } else if (Document::EditMode::Pick == m_document->editMode) { if (m_hoveredNodeItem) { - dust3dDebug << "nodePicked:" << m_hoveredNodeItem->id().toString(); emit nodePicked(m_hoveredNodeItem->id()); } }