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
HEADERS += src/skeletontomesh.h
SOURCES += src/turnaroundloader.cpp
HEADERS += src/turnaroundloader.h
SOURCES += src/theme.cpp
HEADERS += src/theme.h

View File

@ -4,15 +4,20 @@
#include <QGridLayout>
#include <QToolBar>
#include <QThread>
#include <QFileDialog>
#include <assert.h>
#include "mainwindow.h"
#include "skeletoneditwidget.h"
#include "meshlite.h"
#include "skeletontomesh.h"
#include "turnaroundloader.h"
MainWindow::MainWindow() :
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 *motionButton = new QPushButton("Motion");
@ -92,6 +97,12 @@ MainWindow::MainWindow() :
connectResult = connect(m_skeletonEditWidget->graphicsView(), SIGNAL(nodesChanged()), this, SLOT(skeletonChanged()));
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()
@ -122,3 +133,50 @@ void MainWindow::skeletonChanged()
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
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
#define MAIN_WINDOW_H
#include <QMainWindow>
#include <QString>
#include "modelingwidget.h"
#include "skeletoneditwidget.h"
#include "skeletontomesh.h"
#include "turnaroundloader.h"
class MainWindow : public QMainWindow
{
@ -13,11 +15,17 @@ public:
public slots:
void skeletonChanged();
void meshReady();
void turnaroundChanged();
void turnaroundImageReady();
void changeTurnaround();
private:
ModelingWidget *m_modelingWidget;
SkeletonEditWidget *m_skeletonEditWidget;
SkeletonToMesh *m_skeletonToMesh;
bool m_skeletonDirty;
TurnaroundLoader *m_turnaroundLoader;
bool m_turnaroundDirty;
QString m_turnaroundFilename;
};
#endif

View File

@ -118,7 +118,7 @@ static const char *fragmentShaderSourceCore =
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\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"
" fragColor = vec4(col, 1.0);\n"
"}\n";
@ -144,7 +144,7 @@ static const char *fragmentShaderSource =
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\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"
" gl_FragColor = vec4(col, 1.0);\n"
"}\n";

View File

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

View File

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

View File

@ -30,7 +30,8 @@ SkeletonEditGraphicsView *SkeletonEditWidget::graphicsView()
void SkeletonEditWidget::resizeEvent(QResizeEvent *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)

View File

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

View File

@ -1,10 +1,16 @@
#include "theme.h"
QColor Theme::skeletonMasterNodeBorderColor = QColor(0x33, 0x33, 0x33, 128);
QColor Theme::skeletonMasterNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200);
QColor Theme::skeletonMasterNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128);
// 0xfc, 0x66, 0x21
// 252, 102, 33
// 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;
QColor Theme::skeletonSlaveNodeBorderColor = QColor(0x33, 0x33, 0x33, 128);
QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0x00, 0x00, 0x00, 200);
QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 128);
QColor Theme::skeletonSlaveNodeBorderColor = QColor(0xcc, 0xcc, 0xcc, 64);
QColor Theme::skeletonSlaveNodeBorderHighlightColor = QColor(0xfc, 0x66, 0x21, 100);
QColor Theme::skeletonSlaveNodeFillColor = QColor(0xcc, 0xcc, 0xcc, 25);
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