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
|
// 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);
|
CSkeleton *pSkel = mpCharacter->NodeSkeleton(mActiveCharSet);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Editor/UICommon.h"
|
#include "Editor/UICommon.h"
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
CCharacterEditor::CCharacterEditor(QWidget *parent)
|
CCharacterEditor::CCharacterEditor(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
|
@ -47,6 +48,12 @@ CCharacterEditor::CCharacterEditor(QWidget *parent)
|
||||||
connect(ui->PlayPauseButton, SIGNAL(pressed()), this, SLOT(TogglePlay()));
|
connect(ui->PlayPauseButton, SIGNAL(pressed()), this, SLOT(TogglePlay()));
|
||||||
connect(ui->LoopButton, SIGNAL(toggled(bool)), this, SLOT(ToggleLoop(bool)));
|
connect(ui->LoopButton, SIGNAL(toggled(bool)), this, SLOT(ToggleLoop(bool)));
|
||||||
connect(ui->AnimSpeedSpinBox, SIGNAL(valueChanged(double)), this, SLOT(AnimSpeedSpinBoxChanged(double)));
|
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()
|
CCharacterEditor::~CCharacterEditor()
|
||||||
|
@ -139,6 +146,12 @@ void CCharacterEditor::Open()
|
||||||
|
|
||||||
SetActiveAnimation(0);
|
SetActiveAnimation(0);
|
||||||
mpAnimComboBox->blockSignals(false);
|
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();
|
gResCache.Clean();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CCHARACTEREDITOR_H
|
#define CCHARACTEREDITOR_H
|
||||||
|
|
||||||
#include "CCharacterEditorViewport.h"
|
#include "CCharacterEditorViewport.h"
|
||||||
|
#include "CSkeletonHierarchyModel.h"
|
||||||
#include <Core/Scene/CScene.h>
|
#include <Core/Scene/CScene.h>
|
||||||
#include <Core/Scene/CCharacterNode.h>
|
#include <Core/Scene/CCharacterNode.h>
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ class CCharacterEditor : public QMainWindow
|
||||||
CScene *mpScene;
|
CScene *mpScene;
|
||||||
CCharacterNode *mpCharNode;
|
CCharacterNode *mpCharNode;
|
||||||
|
|
||||||
|
CSkeletonHierarchyModel mSkeletonModel;
|
||||||
QComboBox *mpCharComboBox;
|
QComboBox *mpCharComboBox;
|
||||||
QComboBox *mpAnimComboBox;
|
QComboBox *mpAnimComboBox;
|
||||||
QTimer mRefreshTimer;
|
QTimer mRefreshTimer;
|
||||||
|
|
|
@ -14,113 +14,153 @@
|
||||||
<string>Prime World Editor - Character Editor</string>
|
<string>Prime World Editor - Character Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="CentralWidget">
|
<widget class="QWidget" name="CentralWidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="CCharacterEditorViewport" name="Viewport" native="true">
|
<widget class="QSplitter" name="splitter">
|
||||||
<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">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<widget class="QTreeView" name="SkeletonHierarchyTreeView">
|
||||||
</item>
|
<property name="editTriggers">
|
||||||
<item>
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
</property>
|
||||||
<item>
|
<property name="showDropIndicator" stdset="0">
|
||||||
<widget class="QPushButton" name="LoopButton">
|
<bool>false</bool>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Loop</string>
|
<property name="alternatingRowColors">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="checkable">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="selectionMode">
|
||||||
</property>
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
<property name="checked">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="verticalScrollMode">
|
||||||
</property>
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="indentation">
|
||||||
<item>
|
<number>15</number>
|
||||||
<widget class="QPushButton" name="PlayPauseButton">
|
</property>
|
||||||
<property name="text">
|
<property name="rootIsDecorated">
|
||||||
<string>Pause</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="itemsExpandable">
|
||||||
</item>
|
<bool>true</bool>
|
||||||
<item>
|
</property>
|
||||||
<spacer name="horizontalSpacer">
|
<attribute name="headerVisible">
|
||||||
<property name="orientation">
|
<bool>false</bool>
|
||||||
<enum>Qt::Horizontal</enum>
|
</attribute>
|
||||||
</property>
|
</widget>
|
||||||
<property name="sizeHint" stdset="0">
|
<widget class="QWidget" name="">
|
||||||
<size>
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0">
|
||||||
<width>40</width>
|
<item>
|
||||||
<height>20</height>
|
<widget class="CCharacterEditorViewport" name="Viewport" native="true">
|
||||||
</size>
|
<property name="sizePolicy">
|
||||||
</property>
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
</spacer>
|
<horstretch>0</horstretch>
|
||||||
</item>
|
<verstretch>1</verstretch>
|
||||||
<item>
|
</sizepolicy>
|
||||||
<widget class="QLabel" name="AnimSpeedLabel">
|
</property>
|
||||||
<property name="text">
|
</widget>
|
||||||
<string>Speed:</string>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QSlider" name="AnimSlider">
|
||||||
</item>
|
<property name="orientation">
|
||||||
<item>
|
<enum>Qt::Horizontal</enum>
|
||||||
<widget class="WDraggableSpinBox" name="AnimSpeedSpinBox">
|
</property>
|
||||||
<property name="suffix">
|
</widget>
|
||||||
<string>x</string>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
<property name="decimals">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<number>1</number>
|
<item>
|
||||||
</property>
|
<widget class="QPushButton" name="LoopButton">
|
||||||
<property name="minimum">
|
<property name="text">
|
||||||
<double>-10.000000000000000</double>
|
<string>Loop</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="checkable">
|
||||||
<double>10.000000000000000</double>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="singleStep">
|
<property name="checked">
|
||||||
<double>0.100000000000000</double>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
</widget>
|
||||||
<double>1.000000000000000</double>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QPushButton" name="PlayPauseButton">
|
||||||
</item>
|
<property name="text">
|
||||||
</layout>
|
<string>Pause</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QLabel" name="FrameLabel">
|
</item>
|
||||||
<property name="sizePolicy">
|
<item>
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
<spacer name="horizontalSpacer">
|
||||||
<horstretch>0</horstretch>
|
<property name="orientation">
|
||||||
<verstretch>0</verstretch>
|
<enum>Qt::Horizontal</enum>
|
||||||
</sizepolicy>
|
</property>
|
||||||
</property>
|
<property name="sizeHint" stdset="0">
|
||||||
<property name="maximumSize">
|
<size>
|
||||||
<size>
|
<width>40</width>
|
||||||
<width>16777215</width>
|
<height>20</height>
|
||||||
<height>21</height>
|
</size>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
</spacer>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Frame 0 / 0 (0.000s/0.000s)</string>
|
<item>
|
||||||
</property>
|
<widget class="QLabel" name="AnimSpeedLabel">
|
||||||
<property name="textFormat">
|
<property name="text">
|
||||||
<enum>Qt::PlainText</enum>
|
<string>Speed:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
</widget>
|
||||||
<set>Qt::AlignCenter</set>
|
</item>
|
||||||
</property>
|
<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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</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 \
|
CAboutDialog.h \
|
||||||
CharacterEditor/CCharacterEditor.h \
|
CharacterEditor/CCharacterEditor.h \
|
||||||
CharacterEditor/CCharacterEditorViewport.h \
|
CharacterEditor/CCharacterEditorViewport.h \
|
||||||
CGridRenderable.h
|
CGridRenderable.h \
|
||||||
|
CharacterEditor/CSkeletonHierarchyModel.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -218,7 +219,8 @@ SOURCES += \
|
||||||
WorldEditor/CRepackInfoDialog.cpp \
|
WorldEditor/CRepackInfoDialog.cpp \
|
||||||
CAboutDialog.cpp \
|
CAboutDialog.cpp \
|
||||||
CharacterEditor/CCharacterEditor.cpp \
|
CharacterEditor/CCharacterEditor.cpp \
|
||||||
CharacterEditor/CCharacterEditorViewport.cpp
|
CharacterEditor/CCharacterEditorViewport.cpp \
|
||||||
|
CharacterEditor/CSkeletonHierarchyModel.cpp
|
||||||
|
|
||||||
# UI Files
|
# UI Files
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
|
Loading…
Reference in New Issue