Added skeleton hierarchy tree view to the character editor
This commit is contained in:
parent
ce688fcb8e
commit
ed16d05136
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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 += \
|
||||
|
|
Loading…
Reference in New Issue