From ed16d05136cb41fc927b1d5f685a74466ee35cdd Mon Sep 17 00:00:00 2001 From: parax0 Date: Sun, 1 May 2016 20:00:35 -0600 Subject: [PATCH] Added skeleton hierarchy tree view to the character editor --- src/Core/Scene/CCharacterNode.cpp | 4 +- .../CharacterEditor/CCharacterEditor.cpp | 13 + src/Editor/CharacterEditor/CCharacterEditor.h | 2 + .../CharacterEditor/CCharacterEditor.ui | 246 ++++++++++-------- .../CSkeletonHierarchyModel.cpp | 87 +++++++ .../CharacterEditor/CSkeletonHierarchyModel.h | 22 ++ src/Editor/Editor.pro | 6 +- 7 files changed, 273 insertions(+), 107 deletions(-) create mode 100644 src/Editor/CharacterEditor/CSkeletonHierarchyModel.cpp create mode 100644 src/Editor/CharacterEditor/CSkeletonHierarchyModel.h diff --git a/src/Core/Scene/CCharacterNode.cpp b/src/Core/Scene/CCharacterNode.cpp index 633657cf..8a3328f0 100644 --- a/src/Core/Scene/CCharacterNode.cpp +++ b/src/Core/Scene/CCharacterNode.cpp @@ -82,10 +82,10 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, const SVie } } -SRayIntersection CCharacterNode::RayNodeIntersectTest(const CRay& rkRay, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/) +SRayIntersection CCharacterNode::RayNodeIntersectTest(const CRay& rkRay, u32 /*AssetID*/, const SViewInfo& rkViewInfo) { // Check for bone under ray. Doesn't check for model intersections atm - if (mpCharacter) + if (mpCharacter && rkViewInfo.ShowFlags.HasFlag(eShowSkeletons)) { CSkeleton *pSkel = mpCharacter->NodeSkeleton(mActiveCharSet); diff --git a/src/Editor/CharacterEditor/CCharacterEditor.cpp b/src/Editor/CharacterEditor/CCharacterEditor.cpp index b163bf85..498ca4f7 100644 --- a/src/Editor/CharacterEditor/CCharacterEditor.cpp +++ b/src/Editor/CharacterEditor/CCharacterEditor.cpp @@ -3,6 +3,7 @@ #include "Editor/UICommon.h" #include #include +#include CCharacterEditor::CCharacterEditor(QWidget *parent) : QMainWindow(parent) @@ -47,6 +48,12 @@ CCharacterEditor::CCharacterEditor(QWidget *parent) connect(ui->PlayPauseButton, SIGNAL(pressed()), this, SLOT(TogglePlay())); connect(ui->LoopButton, SIGNAL(toggled(bool)), this, SLOT(ToggleLoop(bool))); connect(ui->AnimSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(AnimSpeedSpinBoxChanged(double))); + + // Init skeleton tree view + ui->SkeletonHierarchyTreeView->setModel(&mSkeletonModel); + QList SplitterSizes; + SplitterSizes << width() * 0.2 << width() * 0.8; + ui->splitter->setSizes(SplitterSizes); } CCharacterEditor::~CCharacterEditor() @@ -139,6 +146,12 @@ void CCharacterEditor::Open() SetActiveAnimation(0); mpAnimComboBox->blockSignals(false); + + // Set up skeleton tree view + CSkeleton *pSkel = mpSet->NodeSkeleton(mCurrentChar); + mSkeletonModel.SetSkeleton(pSkel); + ui->SkeletonHierarchyTreeView->expandAll(); + ui->SkeletonHierarchyTreeView->resizeColumnToContents(0); } gResCache.Clean(); diff --git a/src/Editor/CharacterEditor/CCharacterEditor.h b/src/Editor/CharacterEditor/CCharacterEditor.h index 761eddc0..187792e8 100644 --- a/src/Editor/CharacterEditor/CCharacterEditor.h +++ b/src/Editor/CharacterEditor/CCharacterEditor.h @@ -2,6 +2,7 @@ #define CCHARACTEREDITOR_H #include "CCharacterEditorViewport.h" +#include "CSkeletonHierarchyModel.h" #include #include @@ -21,6 +22,7 @@ class CCharacterEditor : public QMainWindow CScene *mpScene; CCharacterNode *mpCharNode; + CSkeletonHierarchyModel mSkeletonModel; QComboBox *mpCharComboBox; QComboBox *mpAnimComboBox; QTimer mRefreshTimer; diff --git a/src/Editor/CharacterEditor/CCharacterEditor.ui b/src/Editor/CharacterEditor/CCharacterEditor.ui index 657db216..a1e49406 100644 --- a/src/Editor/CharacterEditor/CCharacterEditor.ui +++ b/src/Editor/CharacterEditor/CCharacterEditor.ui @@ -14,113 +14,153 @@ Prime World Editor - Character Editor - + - - - - 0 - 1 - - - - - - + Qt::Horizontal - - - - - - - - Loop - - - true - - - true - - - - - - - Pause - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Speed: - - - - - - - x - - - 1 - - - -10.000000000000000 - - - 10.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - - - - 0 - 0 - - - - - 16777215 - 21 - - - - Frame 0 / 0 (0.000s/0.000s) - - - Qt::PlainText - - - Qt::AlignCenter - + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::ScrollPerPixel + + + 15 + + + true + + + true + + + false + + + + + + + + + 0 + 1 + + + + + + + + Qt::Horizontal + + + + + + + + + Loop + + + true + + + true + + + + + + + Pause + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Speed: + + + + + + + x + + + 1 + + + -10.000000000000000 + + + 10.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + + + + 0 + 0 + + + + + 16777215 + 21 + + + + Frame 0 / 0 (0.000s/0.000s) + + + Qt::PlainText + + + Qt::AlignCenter + + + + + diff --git a/src/Editor/CharacterEditor/CSkeletonHierarchyModel.cpp b/src/Editor/CharacterEditor/CSkeletonHierarchyModel.cpp new file mode 100644 index 00000000..e995bcfa --- /dev/null +++ b/src/Editor/CharacterEditor/CSkeletonHierarchyModel.cpp @@ -0,0 +1,87 @@ +#include "CSkeletonHierarchyModel.h" +#include "Editor/UICommon.h" + +CSkeletonHierarchyModel::CSkeletonHierarchyModel(QObject *pParent /*= 0*/) + : QAbstractItemModel(pParent) + , mpSkeleton(nullptr) +{ +} + +QModelIndex CSkeletonHierarchyModel::index(int Row, int Column, const QModelIndex& rkParent) const +{ + if (!hasIndex(Row, Column, rkParent)) + return QModelIndex(); + + if (!rkParent.isValid()) + { + if (mpSkeleton) + return createIndex(Row, Column, mpSkeleton->RootBone()); + else + return QModelIndex(); + } + + CBone *pBone = (CBone*) rkParent.internalPointer(); + if (Row < (int) pBone->NumChildren()) + return createIndex(Row, Column, pBone->ChildByIndex(Row)); + else + return QModelIndex(); +} + +QModelIndex CSkeletonHierarchyModel::parent(const QModelIndex& rkChild) const +{ + CBone *pBone = (CBone*) rkChild.internalPointer(); + + if (pBone->Parent()) + { + // Determine parent index + CBone *pParent = pBone->Parent(); + + if (pParent->Parent()) + { + CBone *pGrandparent = pParent->Parent(); + + for (u32 iChild = 0; iChild < pGrandparent->NumChildren(); iChild++) + { + if (pGrandparent->ChildByIndex(iChild) == pParent) + return createIndex(iChild, 0, pParent); + } + } + + else return createIndex(0, 0, pParent); + } + + return QModelIndex(); +} + +int CSkeletonHierarchyModel::rowCount(const QModelIndex& rkParent) const +{ + if (!mpSkeleton) return 0; + CBone *pBone = (CBone*) rkParent.internalPointer(); + return (pBone ? pBone->NumChildren() : 1); +} + +int CSkeletonHierarchyModel::columnCount(const QModelIndex& /*rkParent*/) const +{ + return 1; +} + +QVariant CSkeletonHierarchyModel::data(const QModelIndex& rkIndex, int Role) const +{ + if (Role == Qt::DisplayRole || Role == Qt::ToolTipRole) + { + CBone *pBone = (CBone*) rkIndex.internalPointer(); + return TO_QSTRING(pBone->Name()); + } + + return QVariant::Invalid; +} + +void CSkeletonHierarchyModel::SetSkeleton(CSkeleton *pSkel) +{ + if (mpSkeleton != pSkel) + { + beginResetModel(); + mpSkeleton = pSkel; + endResetModel(); + } +} diff --git a/src/Editor/CharacterEditor/CSkeletonHierarchyModel.h b/src/Editor/CharacterEditor/CSkeletonHierarchyModel.h new file mode 100644 index 00000000..9560620b --- /dev/null +++ b/src/Editor/CharacterEditor/CSkeletonHierarchyModel.h @@ -0,0 +1,22 @@ +#ifndef CSKELETONHIERARCHYMODEL +#define CSKELETONHIERARCHYMODEL + +#include +#include + +class CSkeletonHierarchyModel : public QAbstractItemModel +{ + CSkeleton *mpSkeleton; + +public: + explicit CSkeletonHierarchyModel(QObject *pParent = 0); + QModelIndex index(int Row, int Column, const QModelIndex& rkParent) const; + QModelIndex parent(const QModelIndex& rkChild) const; + int rowCount(const QModelIndex& rkParent) const; + int columnCount(const QModelIndex& rkParent) const; + QVariant data(const QModelIndex& rkIndex, int Role) const; + void SetSkeleton(CSkeleton *pSkel); +}; + +#endif // CSKELETONHIERARCHYMODEL + diff --git a/src/Editor/Editor.pro b/src/Editor/Editor.pro index ebe614b1..f387b292 100644 --- a/src/Editor/Editor.pro +++ b/src/Editor/Editor.pro @@ -159,7 +159,8 @@ HEADERS += \ CAboutDialog.h \ CharacterEditor/CCharacterEditor.h \ CharacterEditor/CCharacterEditorViewport.h \ - CGridRenderable.h + CGridRenderable.h \ + CharacterEditor/CSkeletonHierarchyModel.h # Source Files SOURCES += \ @@ -218,7 +219,8 @@ SOURCES += \ WorldEditor/CRepackInfoDialog.cpp \ CAboutDialog.cpp \ CharacterEditor/CCharacterEditor.cpp \ - CharacterEditor/CCharacterEditorViewport.cpp + CharacterEditor/CCharacterEditorViewport.cpp \ + CharacterEditor/CSkeletonHierarchyModel.cpp # UI Files FORMS += \