Add XZ switching menu item
parent
7dc096df26
commit
4679381512
|
@ -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.
|
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.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
</pre>
|
</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>
|
||||||
|
|
|
@ -93,6 +93,10 @@ Rotate 90D CCW
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Rotate selected nodes counterclockwise by 90 degrees.
|
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 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.
|
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.
|
||||||
|
|
|
@ -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()
|
std::vector<JointInfo> &JointNodeTree::joints()
|
||||||
{
|
{
|
||||||
return m_tracedJoints;
|
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));
|
const auto &findIt = m_tracedNodeToJointIndexMap.find(std::make_pair(partId, nodeId));
|
||||||
if (findIt == m_tracedNodeToJointIndexMap.end()) {
|
if (findIt == m_tracedNodeToJointIndexMap.end()) {
|
||||||
|
|
|
@ -28,8 +28,9 @@ class JointNodeTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JointNodeTree(MeshResultContext &resultContext);
|
JointNodeTree(MeshResultContext &resultContext);
|
||||||
|
const std::vector<JointInfo> &joints() const;
|
||||||
std::vector<JointInfo> &joints();
|
std::vector<JointInfo> &joints();
|
||||||
int nodeToJointIndex(int partId, int nodeId);
|
int nodeToJointIndex(int partId, int nodeId) const;
|
||||||
void recalculateMatricesAfterPositionUpdated();
|
void recalculateMatricesAfterPositionUpdated();
|
||||||
void recalculateMatricesAfterTransformUpdated();
|
void recalculateMatricesAfterTransformUpdated();
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -530,6 +530,20 @@ void SkeletonDocument::setNodeRadius(QUuid nodeId, float radius)
|
||||||
emit skeletonChanged();
|
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)
|
void SkeletonDocument::setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark)
|
||||||
{
|
{
|
||||||
auto it = nodeMap.find(nodeId);
|
auto it = nodeMap.find(nodeId);
|
||||||
|
|
|
@ -291,6 +291,7 @@ public slots:
|
||||||
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
||||||
void setNodeRadius(QUuid nodeId, float radius);
|
void setNodeRadius(QUuid nodeId, float radius);
|
||||||
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
|
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
|
||||||
|
void switchNodeXZ(QUuid nodeId);
|
||||||
void moveOriginBy(float x, float y, float z);
|
void moveOriginBy(float x, float y, float z);
|
||||||
void addEdge(QUuid fromNodeId, QUuid toNodeId);
|
void addEdge(QUuid fromNodeId, QUuid toNodeId);
|
||||||
void setEditMode(SkeletonDocumentEditMode mode);
|
void setEditMode(SkeletonDocumentEditMode mode);
|
||||||
|
|
|
@ -316,6 +316,12 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
|
||||||
});
|
});
|
||||||
m_editMenu->addAction(m_rotateCounterclockwiseAction);
|
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_alignToMenu = new QMenu(tr("Align To"));
|
||||||
|
|
||||||
m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this);
|
m_alignToGlobalCenterAction = new QAction(tr("Global Center"), this);
|
||||||
|
@ -390,6 +396,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
|
||||||
m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
|
m_flipVerticallyAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
|
||||||
m_rotateClockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
|
m_rotateClockwiseAction->setEnabled(m_graphicsWidget->hasMultipleSelection());
|
||||||
m_rotateCounterclockwiseAction->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_alignToGlobalCenterAction->setEnabled(m_graphicsWidget->hasSelection() && m_document->originSettled());
|
||||||
m_alignToGlobalVerticalCenterAction->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());
|
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::moveOriginBy, m_document, &SkeletonDocument::moveOriginBy);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::partChecked, m_document, &SkeletonDocument::partChecked);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::partChecked, m_document, &SkeletonDocument::partChecked);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::partUnchecked, m_document, &SkeletonDocument::partUnchecked);
|
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::setPartLockState, m_document, &SkeletonDocument::setPartLockState);
|
||||||
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartVisibleState, m_document, &SkeletonDocument::setPartVisibleState);
|
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartVisibleState, m_document, &SkeletonDocument::setPartVisibleState);
|
||||||
|
|
|
@ -96,6 +96,7 @@ private:
|
||||||
QAction *m_flipVerticallyAction;
|
QAction *m_flipVerticallyAction;
|
||||||
QAction *m_rotateClockwiseAction;
|
QAction *m_rotateClockwiseAction;
|
||||||
QAction *m_rotateCounterclockwiseAction;
|
QAction *m_rotateCounterclockwiseAction;
|
||||||
|
QAction *m_switchXzAction;
|
||||||
|
|
||||||
QMenu *m_alignToMenu;
|
QMenu *m_alignToMenu;
|
||||||
QAction *m_alignToGlobalCenterAction;
|
QAction *m_alignToGlobalCenterAction;
|
||||||
|
|
|
@ -187,6 +187,12 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
|
||||||
contextMenu.addAction(&rotateCounterclockwiseAction);
|
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 alignToLocalCenterAction(tr("Local Center"), this);
|
||||||
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
|
QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this);
|
||||||
QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal 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)
|
void SkeletonGraphicsWidget::zoomSelected(float delta)
|
||||||
{
|
{
|
||||||
if (m_rangeSelectionSet.empty())
|
if (m_rangeSelectionSet.empty())
|
||||||
|
@ -1796,6 +1820,7 @@ void SkeletonGraphicsWidget::readSkeletonNodeAndEdgeIdSetFromRangeSelection(std:
|
||||||
if (item->data(0) == "node") {
|
if (item->data(0) == "node") {
|
||||||
nodeIdSet->insert(((SkeletonGraphicsNodeItem *)item)->id());
|
nodeIdSet->insert(((SkeletonGraphicsNodeItem *)item)->id());
|
||||||
} else if (item->data(0) == "edge") {
|
} else if (item->data(0) == "edge") {
|
||||||
|
if (nullptr != edgeIdSet)
|
||||||
edgeIdSet->insert(((SkeletonGraphicsEdgeItem *)item)->id());
|
edgeIdSet->insert(((SkeletonGraphicsEdgeItem *)item)->id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,6 +385,7 @@ signals:
|
||||||
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
void setNodeOrigin(QUuid nodeId, float x, float y, float z);
|
||||||
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
|
void setNodeBoneMark(QUuid nodeId, SkeletonBoneMark mark);
|
||||||
void zoomRenderedModelBy(float delta);
|
void zoomRenderedModelBy(float delta);
|
||||||
|
void switchNodeXZ(QUuid nodeId);
|
||||||
public:
|
public:
|
||||||
SkeletonGraphicsWidget(const SkeletonDocument *document);
|
SkeletonGraphicsWidget(const SkeletonDocument *document);
|
||||||
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
|
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
|
||||||
|
@ -399,7 +400,7 @@ public:
|
||||||
QUuid querySkeletonItemPartId(QGraphicsItem *item);
|
QUuid querySkeletonItemPartId(QGraphicsItem *item);
|
||||||
static SkeletonProfile readSkeletonItemProfile(QGraphicsItem *item);
|
static SkeletonProfile readSkeletonItemProfile(QGraphicsItem *item);
|
||||||
void readMergedSkeletonNodeSetFromRangeSelection(std::set<SkeletonGraphicsNodeItem *> *nodeItemSet);
|
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 readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem **nodeItem, SkeletonGraphicsEdgeItem **edgeItem);
|
||||||
bool hasSelection();
|
bool hasSelection();
|
||||||
bool hasItems();
|
bool hasItems();
|
||||||
|
@ -463,6 +464,7 @@ public slots:
|
||||||
void ikMoveReady();
|
void ikMoveReady();
|
||||||
void setSelectedNodesBoneMark(SkeletonBoneMark boneMark);
|
void setSelectedNodesBoneMark(SkeletonBoneMark boneMark);
|
||||||
void timeToRemoveDeferredNodesAndEdges();
|
void timeToRemoveDeferredNodesAndEdges();
|
||||||
|
void switchSelectedXZ();
|
||||||
private slots:
|
private slots:
|
||||||
void turnaroundImageReady();
|
void turnaroundImageReady();
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue