Add turnaround image loader

master
Jeremy Hu 2018-03-13 14:39:36 +08:00
parent 0ee18d41a8
commit ce20e49883
12 changed files with 171 additions and 21 deletions

View File

@ -24,6 +24,9 @@ HEADERS += src/skeletoneditedgeitem.h
SOURCES += src/skeletontomesh.cpp SOURCES += src/skeletontomesh.cpp
HEADERS += src/skeletontomesh.h HEADERS += src/skeletontomesh.h
SOURCES += src/turnaroundloader.cpp
HEADERS += src/turnaroundloader.h
SOURCES += src/theme.cpp SOURCES += src/theme.cpp
HEADERS += src/theme.h HEADERS += src/theme.h

View File

@ -4,15 +4,20 @@
#include <QGridLayout> #include <QGridLayout>
#include <QToolBar> #include <QToolBar>
#include <QThread> #include <QThread>
#include <QFileDialog>
#include <assert.h> #include <assert.h>
#include "mainwindow.h" #include "mainwindow.h"
#include "skeletoneditwidget.h" #include "skeletoneditwidget.h"
#include "meshlite.h" #include "meshlite.h"
#include "skeletontomesh.h" #include "skeletontomesh.h"
#include "turnaroundloader.h"
MainWindow::MainWindow() : MainWindow::MainWindow() :
m_skeletonToMesh(NULL), m_skeletonToMesh(NULL),
m_skeletonDirty(false) m_skeletonDirty(false),
m_turnaroundLoader(NULL),
m_turnaroundDirty(false)
//m_turnaroundFilename("../assets/male_werewolf_turnaround_lineart_by_jennette_brown.png")
{ {
QPushButton *skeletonButton = new QPushButton("Skeleton"); QPushButton *skeletonButton = new QPushButton("Skeleton");
QPushButton *motionButton = new QPushButton("Motion"); QPushButton *motionButton = new QPushButton("Motion");
@ -92,6 +97,12 @@ MainWindow::MainWindow() :
connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(nodesChanged()), this, SLOT(skeletonChanged())); connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(nodesChanged()), this, SLOT(skeletonChanged()));
assert(connectResult); assert(connectResult);
connectResult = connect(m_skeletonEditWidget, SIGNAL(sizeChanged()), this, SLOT(turnaroundChanged()));
assert(connectResult);
connectResult = connect(changeTurnaroundButton, SIGNAL(released()), this, SLOT(changeTurnaround()));
assert(connectResult);
} }
void MainWindow::meshReady() void MainWindow::meshReady()
@ -122,3 +133,50 @@ void MainWindow::skeletonChanged()
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start(); thread->start();
} }
void MainWindow::turnaroundChanged()
{
if (m_turnaroundFilename.isEmpty())
return;
if (m_turnaroundLoader) {
m_turnaroundDirty = true;
return;
}
m_turnaroundDirty = false;
QThread *thread = new QThread;
m_turnaroundLoader = new TurnaroundLoader(m_turnaroundFilename,
m_skeletonEditWidget->rect().size());
m_turnaroundLoader->moveToThread(thread);
connect(thread, SIGNAL(started()), m_turnaroundLoader, SLOT(process()));
connect(m_turnaroundLoader, SIGNAL(finished()), this, SLOT(turnaroundImageReady()));
connect(m_turnaroundLoader, SIGNAL(finished()), thread, SLOT(quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
void MainWindow::turnaroundImageReady()
{
QImage *backgroundImage = m_turnaroundLoader->takeResultImage();
if (backgroundImage && backgroundImage->width() > 0 && backgroundImage->height() > 0)
m_skeletonEditWidget->graphicsView()->updateBackgroundImage(*backgroundImage);
delete backgroundImage;
delete m_turnaroundLoader;
m_turnaroundLoader = NULL;
if (m_turnaroundDirty) {
turnaroundChanged();
}
}
void MainWindow::changeTurnaround()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Turnaround Reference Image"),
QString(),
tr("Image Files (*.png *.jpg *.bmp)")).trimmed();
if (fileName.isEmpty())
return;
m_turnaroundFilename = fileName;
turnaroundChanged();
}

View File

@ -1,9 +1,11 @@
#ifndef MAIN_WINDOW_H #ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H #define MAIN_WINDOW_H
#include <QMainWindow> #include <QMainWindow>
#include <QString>
#include "modelingwidget.h" #include "modelingwidget.h"
#include "skeletoneditwidget.h" #include "skeletoneditwidget.h"
#include "skeletontomesh.h" #include "skeletontomesh.h"
#include "turnaroundloader.h"
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
@ -13,11 +15,17 @@ public:
public slots: public slots:
void skeletonChanged(); void skeletonChanged();
void meshReady(); void meshReady();
void turnaroundChanged();
void turnaroundImageReady();
void changeTurnaround();
private: private:
ModelingWidget *m_modelingWidget; ModelingWidget *m_modelingWidget;
SkeletonEditWidget *m_skeletonEditWidget; SkeletonEditWidget *m_skeletonEditWidget;
SkeletonToMesh *m_skeletonToMesh; SkeletonToMesh *m_skeletonToMesh;
bool m_skeletonDirty; bool m_skeletonDirty;
TurnaroundLoader *m_turnaroundLoader;
bool m_turnaroundDirty;
QString m_turnaroundFilename;
}; };
#endif #endif

View File

@ -118,7 +118,7 @@ static const char *fragmentShaderSourceCore =
"void main() {\n" "void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n" " highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n" " highp vec3 color = vec3(0.99, 0.4, 0.13);\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" fragColor = vec4(col, 1.0);\n" " fragColor = vec4(col, 1.0);\n"
"}\n"; "}\n";
@ -144,7 +144,7 @@ static const char *fragmentShaderSource =
"void main() {\n" "void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n" " highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(1.0, 1.0, 1.0);\n" " highp vec3 color = vec3(0.99, 0.4, 0.13);\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" gl_FragColor = vec4(col, 1.0);\n" " gl_FragColor = vec4(col, 1.0);\n"
"}\n"; "}\n";

View File

@ -14,23 +14,21 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
m_nextStartNodeItem(NULL), m_nextStartNodeItem(NULL),
m_lastHoverNodeItem(NULL), m_lastHoverNodeItem(NULL),
m_lastMousePos(0, 0), m_lastMousePos(0, 0),
m_isMovingNodeItem(false) m_isMovingNodeItem(false),
m_backgroundLoaded(false)
{ {
setScene(new QGraphicsScene()); setScene(new QGraphicsScene());
setMouseTracking(true); m_backgroundItem = new QGraphicsPixmapItem();
QImage image("../assets/male_werewolf_turnaround_lineart_by_jennette_brown.png");
m_backgroundItem = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene()->addItem(m_backgroundItem); scene()->addItem(m_backgroundItem);
m_pendingNodeItem = new QGraphicsEllipseItem(0, 0, m_initialNodeSize, m_initialNodeSize); m_pendingNodeItem = new QGraphicsEllipseItem(0, 0, m_initialNodeSize, m_initialNodeSize);
m_pendingNodeItem->setVisible(false);
scene()->addItem(m_pendingNodeItem); scene()->addItem(m_pendingNodeItem);
m_pendingEdgeItem = new QGraphicsLineItem(0, 0, 0, 0); m_pendingEdgeItem = new QGraphicsLineItem(0, 0, 0, 0);
m_pendingEdgeItem->setVisible(false);
scene()->addItem(m_pendingEdgeItem); scene()->addItem(m_pendingEdgeItem);
applyAddNodeMode();
} }
void SkeletonEditGraphicsView::toggleAddNodeMode() void SkeletonEditGraphicsView::toggleAddNodeMode()
@ -75,6 +73,9 @@ SkeletonEditNodeItem *SkeletonEditGraphicsView::findNodeItemByPos(QPointF pos)
void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event) void SkeletonEditGraphicsView::mousePressEvent(QMouseEvent *event)
{ {
QWidget::mousePressEvent(event);
if (!m_backgroundLoaded)
return;
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (!m_inAddNodeMode) { if (!m_inAddNodeMode) {
if (m_lastHoverNodeItem) { if (m_lastHoverNodeItem) {
@ -93,6 +94,9 @@ float SkeletonEditGraphicsView::findXForSlave(float x)
void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event) void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{ {
QWidget::mouseReleaseEvent(event);
if (!m_backgroundLoaded)
return;
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if (m_inAddNodeMode) { if (m_inAddNodeMode) {
SkeletonEditNodeItem *masterNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect()); SkeletonEditNodeItem *masterNode = new SkeletonEditNodeItem(m_pendingNodeItem->rect());
@ -114,9 +118,7 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
} }
m_isMovingNodeItem = false; m_isMovingNodeItem = false;
} else if (event->button() == Qt::RightButton) { } else if (event->button() == Qt::RightButton) {
if (m_inAddNodeMode) { toggleAddNodeMode();
toggleAddNodeMode();
}
} }
} }
@ -136,6 +138,8 @@ bool SkeletonEditGraphicsView::canNodeItemMoveTo(SkeletonEditNodeItem *item, QPo
void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event) void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
{ {
QWidget::mouseMoveEvent(event); QWidget::mouseMoveEvent(event);
if (!m_backgroundLoaded)
return;
QPointF pos = mapToScene(event->pos()); QPointF pos = mapToScene(event->pos());
QPointF moveTo = QPointF(pos.x() - m_pendingNodeItem->rect().width() / 2, pos.y() - m_pendingNodeItem->rect().height() / 2); QPointF moveTo = QPointF(pos.x() - m_pendingNodeItem->rect().width() / 2, pos.y() - m_pendingNodeItem->rect().height() / 2);
if (moveTo.x() < 0) if (moveTo.x() < 0)
@ -251,6 +255,8 @@ bool SkeletonEditGraphicsView::canAddItemRadius(QGraphicsEllipseItem *item, floa
void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event) void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
{ {
QWidget::wheelEvent(event); QWidget::wheelEvent(event);
if (!m_backgroundLoaded)
return;
qreal delta = event->delta(); qreal delta = event->delta();
AddItemRadius(m_pendingNodeItem, delta); AddItemRadius(m_pendingNodeItem, delta);
if (!m_inAddNodeMode && m_lastHoverNodeItem) { if (!m_inAddNodeMode && m_lastHoverNodeItem) {
@ -274,3 +280,13 @@ void SkeletonEditGraphicsView::setNextStartNodeItem(SkeletonEditNodeItem *item)
m_nextStartNodeItem->setIsNextStartNode(true); m_nextStartNodeItem->setIsNextStartNode(true);
} }
void SkeletonEditGraphicsView::updateBackgroundImage(const QImage &image)
{
QPixmap pixmap = QPixmap::fromImage(image);
m_backgroundItem->setPixmap(pixmap);
scene()->setSceneRect(pixmap.rect());
if (!m_backgroundLoaded) {
m_backgroundLoaded = true;
applyAddNodeMode();
}
}

View File

@ -15,6 +15,7 @@ public slots:
void turnOnAddNodeMode(); void turnOnAddNodeMode();
public: public:
SkeletonEditGraphicsView(QWidget *parent = 0); SkeletonEditGraphicsView(QWidget *parent = 0);
void updateBackgroundImage(const QImage &image);
protected: protected:
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event); void wheelEvent(QWheelEvent *event);
@ -31,6 +32,7 @@ private:
SkeletonEditNodeItem *m_lastHoverNodeItem; SkeletonEditNodeItem *m_lastHoverNodeItem;
QPointF m_lastMousePos; QPointF m_lastMousePos;
bool m_isMovingNodeItem; bool m_isMovingNodeItem;
bool m_backgroundLoaded;
void toggleAddNodeMode(); void toggleAddNodeMode();
void applyAddNodeMode(); void applyAddNodeMode();
SkeletonEditNodeItem *findNodeItemByPos(QPointF pos); SkeletonEditNodeItem *findNodeItemByPos(QPointF pos);

View File

@ -31,11 +31,13 @@ SkeletonEditNodeItem *SkeletonEditNodeItem::master()
void SkeletonEditNodeItem::setMaster(SkeletonEditNodeItem *nodeItem) void SkeletonEditNodeItem::setMaster(SkeletonEditNodeItem *nodeItem)
{ {
m_master = nodeItem; m_master = nodeItem;
updateBorder();
} }
void SkeletonEditNodeItem::setSlave(SkeletonEditNodeItem *nodeItem) void SkeletonEditNodeItem::setSlave(SkeletonEditNodeItem *nodeItem)
{ {
m_slave = nodeItem; m_slave = nodeItem;
updateBorder();
} }
SkeletonEditNodeItem *SkeletonEditNodeItem::pair() SkeletonEditNodeItem *SkeletonEditNodeItem::pair()

View File

@ -30,7 +30,8 @@ SkeletonEditGraphicsView *SkeletonEditWidget::graphicsView()
void SkeletonEditWidget::resizeEvent(QResizeEvent *event) void SkeletonEditWidget::resizeEvent(QResizeEvent *event)
{ {
QFrame::resizeEvent(event); QFrame::resizeEvent(event);
m_graphicsView->fitInView(QRectF(0, 0, m_graphicsView->scene()->width(), m_graphicsView->scene()->height()), Qt::KeepAspectRatio); //m_graphicsView->fitInView(QRectF(0, 0, m_graphicsView->scene()->width(), m_graphicsView->scene()->height()), Qt::KeepAspectRatio);
emit sizeChanged();
} }
void SkeletonEditWidget::mouseMoveEvent(QMouseEvent *event) void SkeletonEditWidget::mouseMoveEvent(QMouseEvent *event)

View File

@ -11,6 +11,8 @@
class SkeletonEditWidget : public QFrame class SkeletonEditWidget : public QFrame
{ {
Q_OBJECT Q_OBJECT
signals:
void sizeChanged();
public: public:
SkeletonEditWidget(QFrame *parent = 0); SkeletonEditWidget(QFrame *parent = 0);
SkeletonEditGraphicsView *graphicsView(); SkeletonEditGraphicsView *graphicsView();

View File

@ -1,10 +1,16 @@
#include "theme.h" #include "theme.h"
QColor Theme::skeletonMasterNodeBorderColor = QColor(0x33, 0x33, 0x33, 128); // 0xfc, 0x66, 0x21
QColor Theme::skeletonMasterNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200); // 252, 102, 33
QColor Theme::skeletonMasterNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128); // 0.99, 0.4, 0.13
QColor Theme::skeletonMasterNodeBorderColor = QColor(0xfc, 0x66, 0x21, 128);
QColor Theme::skeletonMasterNodeBorderHighlightColor = QColor(0xfc, 0x66, 0x21, 200);
QColor Theme::skeletonMasterNodeFillColor = QColor(0xfc, 0x66, 0x21, 50);
int Theme::skeletonMasterNodeBorderSize = 15; int Theme::skeletonMasterNodeBorderSize = 15;
QColor Theme::skeletonSlaveNodeBorderColor = QColor(0x33, 0x33, 0x33, 128); QColor Theme::skeletonSlaveNodeBorderColor = QColor(0xcc, 0xcc, 0xcc, 64);
QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200); QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0xfc, 0x66, 0x21, 100);
QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128); QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 25);
int Theme::skeletonSlaveNodeBorderSize = 15; int Theme::skeletonSlaveNodeBorderSize = 15;

27
src/turnaroundloader.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "turnaroundloader.h"
TurnaroundLoader::TurnaroundLoader(const QString &filename, QSize viewSize) :
m_resultImage(NULL)
{
m_filename = filename;
m_viewSize = viewSize;
}
TurnaroundLoader::~TurnaroundLoader()
{
delete m_resultImage;
}
QImage *TurnaroundLoader::takeResultImage()
{
QImage *returnImage = m_resultImage;
m_resultImage = NULL;
return returnImage;
}
void TurnaroundLoader::process()
{
QImage image(m_filename);
m_resultImage = new QImage(image.scaled(m_viewSize, Qt::KeepAspectRatio));
emit finished();
}

25
src/turnaroundloader.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef TURNAROUND_LOADER_H
#define TURNAROUND_LOADER_H
#include <QObject>
#include <QString>
#include <QSize>
#include <QImage>
class TurnaroundLoader : public QObject
{
Q_OBJECT
public:
TurnaroundLoader(const QString &filename, QSize viewSize);
~TurnaroundLoader();
QImage *takeResultImage();
signals:
void finished();
public slots:
void process();
private:
QImage *m_resultImage;
QString m_filename;
QSize m_viewSize;
};
#endif