Add XZ switching menu item

master
Jeremy Hu 2018-06-21 16:24:18 +08:00
parent 7dc096df26
commit 4679381512
10 changed files with 71 additions and 4 deletions

View File

@ -557,3 +557,9 @@ https://www.reddit.com/r/gamedev/comments/5iuf3h/i_am_writting_a_3d_monster_mode
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
</pre>
<h1>Ahmad Abdul Karim, Alexandre Meyer, Thibaut Gaudin, Axel Buendia and Saida Bouakaz1</h1>
<pre>
Generic Spine Model with Simple Physics for Life-Like Quadrupeds and Reptiles
http://liris.cnrs.fr/Documents/Liris-5778.pdf
</pre>

View File

@ -93,6 +93,10 @@ Rotate 90D CCW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rotate selected nodes counterclockwise by 90 degrees.
Switch XZ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Switch selected nodes' X and Z position. if you accidentally put some parts in front view which you planned put into side view, you can select these nodes and switch the XZ components.
Align To
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Align selected nodes with center anchor globally or selected nodes' center locally. Normally, the center anchor(a Triangle) is not show up, you can turn on the Part Mirror to make it visible, then turn Part Mirror off, the center anchor would not gone once showed.

View File

@ -79,12 +79,17 @@ void JointNodeTree::traceBoneFromJoint(MeshResultContext &resultContext, std::pa
}
}
const std::vector<JointInfo> &JointNodeTree::joints() const
{
return m_tracedJoints;
}
std::vector<JointInfo> &JointNodeTree::joints()
{
return m_tracedJoints;
}
int JointNodeTree::nodeToJointIndex(int partId, int nodeId)
int JointNodeTree::nodeToJointIndex(int partId, int nodeId) const
{
const auto &findIt = m_tracedNodeToJointIndexMap.find(std::make_pair(partId, nodeId));
if (findIt == m_tracedNodeToJointIndexMap.end()) {

View File

@ -28,8 +28,9 @@ class JointNodeTree
{
public:
JointNodeTree(MeshResultContext &resultContext);
const std::vector<JointInfo> &joints() const;
std::vector<JointInfo> &joints();
int nodeToJointIndex(int partId, int nodeId);
int nodeToJointIndex(int partId, int nodeId) const;
void recalculateMatricesAfterPositionUpdated();
void recalculateMatricesAfterTransformUpdated();
private:

View File

@ -530,6 +530,20 @@ void SkeletonDocument::setNodeRadius(QUuid nodeId, float radius)
emit skeletonChanged();
}
void SkeletonDocument::switchNodeXZ(QUuid nodeId)
{
auto it = nodeMap.find(nodeId);
if (it == nodeMap.end()) {
qDebug() << "Find node failed:" << nodeId;
return;
}
if (isPartReadonly(it->second.partId))
return;
std::swap(it->second.x, it->second.z);
emit nodeOriginChanged(nodeId);
emit skeletonChanged();
}
void SkeletonDocument::setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark)
{
auto it = nodeMap.find(nodeId);

View File

@ -291,6 +291,7 @@ public slots:
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
void setNodeRadius(QUuid nodeId, float radius);
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
void switchNodeXZ(QUuid nodeId);
void moveOriginBy(float x, float y, float z);
void addEdge(QUuid fromNodeId, QUuid toNodeId);
void setEditMode(SkeletonDocumentEditMode mode);

View File

@ -316,6 +316,12 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
});
m_editMenu->addAction(m_rotateCounterclockwiseAction);
m_switchXzAction = new QAction(tr("Switch XZ"), this);
connect(m_switchXzAction, &QAction::triggered, [=] {
m_graphicsWidget->switchSelectedXZ();
});
m_editMenu->addAction(m_switchXzAction);
m_alignToMenu = new QMenu(tr("Align To"));
m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this);
@ -390,6 +396,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_rotateClockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_rotateCounterclockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
m_switchXzAction->setEnabled(m_graphicsWidget->hasSelection());
m_alignToGlobalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
m_alignToGlobalVerticalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
m_alignToGlobalHorizontalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
@ -547,6 +554,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(graphicsWidget, &SkeletonGraphicsWidget::moveOriginBy, m_document, &SkeletonDocument::moveOriginBy);
connect(graphicsWidget, &SkeletonGraphicsWidget::partChecked, m_document, &SkeletonDocument::partChecked);
connect(graphicsWidget, &SkeletonGraphicsWidget::partUnchecked, m_document, &SkeletonDocument::partUnchecked);
connect(graphicsWidget, &SkeletonGraphicsWidget::switchNodeXZ, m_document, &SkeletonDocument::switchNodeXZ);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartLockState, m_document, &SkeletonDocument::setPartLockState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartVisibleState, m_document, &SkeletonDocument::setPartVisibleState);

View File

@ -96,6 +96,7 @@ private:
QAction *m_flipVerticallyAction;
QAction *m_rotateClockwiseAction;
QAction *m_rotateCounterclockwiseAction;
QAction *m_switchXzAction;
QMenu *m_alignToMenu;
QAction *m_alignToGlobalCenterAction;

View File

@ -187,6 +187,12 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
contextMenu.addAction(&rotateCounterclockwiseAction);
}
QAction switchXzAction(tr("Switch XZ"), this);
if (hasSelection()) {
connect(&switchXzAction, &QAction::triggered, this, &SkeletonGraphicsWidget::switchSelectedXZ);
contextMenu.addAction(&switchXzAction);
}
QAction alignToLocalCenterAction(tr("Local Center"), this);
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal Center"), this);
@ -844,6 +850,24 @@ void SkeletonGraphicsWidget::moveSelected(float byX, float byY)
}
}
void SkeletonGraphicsWidget::switchSelectedXZ()
{
if (m_rangeSelectionSet.empty())
return;
std::set<QUuid> nodeIdSet;
readSkeletonNodeAndEdgeIdSetFromRangeSelection(&nodeIdSet);
if (nodeIdSet.empty())
return;
emit batchChangeBegin();
for (const auto nodeId: nodeIdSet) {
emit switchNodeXZ(nodeId);
}
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::zoomSelected(float delta)
{
if (m_rangeSelectionSet.empty())
@ -1796,6 +1820,7 @@ void SkeletonGraphicsWidget::readSkeletonNodeAndEdgeIdSetFromRangeSelection(std:
if (item->data(0) == "node") {
nodeIdSet->insert(((SkeletonGraphicsNodeItem *)item)->id());
} else if (item->data(0) == "edge") {
if (nullptr != edgeIdSet)
edgeIdSet->insert(((SkeletonGraphicsEdgeItem *)item)->id());
}
}

View File

@ -385,6 +385,7 @@ signals:
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
void zoomRenderedModelBy(float delta);
void switchNodeXZ(QUuid nodeId);
public:
SkeletonGraphicsWidget(const SkeletonDocument *document);
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
@ -399,7 +400,7 @@ public:
QUuid querySkeletonItemPartId(QGraphicsItem *item);
static SkeletonProfile readSkeletonItemProfile(QGraphicsItem *item);
void readMergedSkeletonNodeSetFromRangeSelection(std::set<SkeletonGraphicsNodeItem *> *nodeItemSet);
void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set<QUuid> *nodeIdSet, std::set<QUuid> *edgeIdSet);
void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set<QUuid> *nodeIdSet, std::set<QUuid> *edgeIdSet=nullptr);
bool readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem **nodeItem, SkeletonGraphicsEdgeItem **edgeItem);
bool hasSelection();
bool hasItems();
@ -463,6 +464,7 @@ public slots:
void ikMoveReady();
void setSelectedNodesBoneMark(SkeletonBoneMark boneMark);
void timeToRemoveDeferredNodesAndEdges();
void switchSelectedXZ();
private slots:
void turnaroundImageReady();
private: