diff --git a/dust3d.pro b/dust3d.pro index c43c644a..4402e042 100644 --- a/dust3d.pro +++ b/dust3d.pro @@ -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 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 48fd887f..51779724 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4,15 +4,20 @@ #include #include #include +#include #include #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(); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 543d8773..3681d526 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -1,9 +1,11 @@ #ifndef MAIN_WINDOW_H #define MAIN_WINDOW_H #include +#include #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 diff --git a/src/modelingwidget.cpp b/src/modelingwidget.cpp index 432d088d..3618425d 100644 --- a/src/modelingwidget.cpp +++ b/src/modelingwidget.cpp @@ -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"; diff --git a/src/skeletoneditgraphicsview.cpp b/src/skeletoneditgraphicsview.cpp index 3a4ed1e2..3679af2f 100644 --- a/src/skeletoneditgraphicsview.cpp +++ b/src/skeletoneditgraphicsview.cpp @@ -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,9 +118,7 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event) } m_isMovingNodeItem = false; } 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) { 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(); + } +} diff --git a/src/skeletoneditgraphicsview.h b/src/skeletoneditgraphicsview.h index 6b78e8f8..bfd67c2f 100644 --- a/src/skeletoneditgraphicsview.h +++ b/src/skeletoneditgraphicsview.h @@ -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); diff --git a/src/skeletoneditnodeitem.cpp b/src/skeletoneditnodeitem.cpp index e29821b9..54b4e231 100644 --- a/src/skeletoneditnodeitem.cpp +++ b/src/skeletoneditnodeitem.cpp @@ -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() diff --git a/src/skeletoneditwidget.cpp b/src/skeletoneditwidget.cpp index 7fe88055..cc29c0db 100644 --- a/src/skeletoneditwidget.cpp +++ b/src/skeletoneditwidget.cpp @@ -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) diff --git a/src/skeletoneditwidget.h b/src/skeletoneditwidget.h index d28a37cf..9625688a 100644 --- a/src/skeletoneditwidget.h +++ b/src/skeletoneditwidget.h @@ -11,6 +11,8 @@ class SkeletonEditWidget : public QFrame { Q_OBJECT +signals: + void sizeChanged(); public: SkeletonEditWidget(QFrame *parent = 0); SkeletonEditGraphicsView *graphicsView(); diff --git a/src/theme.cpp b/src/theme.cpp index 61aba809..54c0e88b 100644 --- a/src/theme.cpp +++ b/src/theme.cpp @@ -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; + + diff --git a/src/turnaroundloader.cpp b/src/turnaroundloader.cpp new file mode 100644 index 00000000..145786c6 --- /dev/null +++ b/src/turnaroundloader.cpp @@ -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(); +} diff --git a/src/turnaroundloader.h b/src/turnaroundloader.h new file mode 100644 index 00000000..219a121a --- /dev/null +++ b/src/turnaroundloader.h @@ -0,0 +1,25 @@ +#ifndef TURNAROUND_LOADER_H +#define TURNAROUND_LOADER_H +#include +#include +#include +#include + +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