Added skeleton hierarchy tree view to the character editor

This commit is contained in:
parax0 2016-05-01 20:00:35 -06:00
parent ce688fcb8e
commit ed16d05136
7 changed files with 273 additions and 107 deletions

View File

@ -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);

View File

@ -3,6 +3,7 @@
#include "Editor/UICommon.h"
#include <Math/MathUtil.h>
#include <QFileDialog>
#include <QTreeView>
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<int> 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();

View File

@ -2,6 +2,7 @@
#define CCHARACTEREDITOR_H
#include "CCharacterEditorViewport.h"
#include "CSkeletonHierarchyModel.h"
#include <Core/Scene/CScene.h>
#include <Core/Scene/CCharacterNode.h>
@ -21,6 +22,7 @@ class CCharacterEditor : public QMainWindow
CScene *mpScene;
CCharacterNode *mpCharNode;
CSkeletonHierarchyModel mSkeletonModel;
QComboBox *mpCharComboBox;
QComboBox *mpAnimComboBox;
QTimer mRefreshTimer;

View File

@ -14,113 +14,153 @@
<string>Prime World Editor - Character Editor</string>
</property>
<widget class="QWidget" name="CentralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="CCharacterEditorViewport" name="Viewport" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="AnimSlider">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="LoopButton">
<property name="text">
<string>Loop</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PlayPauseButton">
<property name="text">
<string>Pause</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="AnimSpeedLabel">
<property name="text">
<string>Speed:</string>
</property>
</widget>
</item>
<item>
<widget class="WDraggableSpinBox" name="AnimSpeedSpinBox">
<property name="suffix">
<string>x</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="FrameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>Frame 0 / 0 (0.000s/0.000s)</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<widget class="QTreeView" name="SkeletonHierarchyTreeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>15</number>
</property>
<property name="rootIsDecorated">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
<widget class="QWidget" name="">
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0">
<item>
<widget class="CCharacterEditorViewport" name="Viewport" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="AnimSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="LoopButton">
<property name="text">
<string>Loop</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PlayPauseButton">
<property name="text">
<string>Pause</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="AnimSpeedLabel">
<property name="text">
<string>Speed:</string>
</property>
</widget>
</item>
<item>
<widget class="WDraggableSpinBox" name="AnimSpeedSpinBox">
<property name="suffix">
<string>x</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="FrameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>Frame 0 / 0 (0.000s/0.000s)</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -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();
}
}

View File

@ -0,0 +1,22 @@
#ifndef CSKELETONHIERARCHYMODEL
#define CSKELETONHIERARCHYMODEL
#include <QAbstractItemModel>
#include <Core/Resource/CSkeleton.h>
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

View File

@ -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 += \