From f3e38983d77c72f3121c33a149a58fdf9c64158c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kera=CC=88nen=20Pasi?= Date: Fri, 23 Aug 2013 16:17:29 +0300 Subject: New 3D scene for lights and camera setup for input handlers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib909bd818364c1646615df7c543d57b07b920a83 Reviewed-by: Tomi Korpipää --- src/datavis3d/engine/abstract3dcontroller.cpp | 189 ++++++++-- src/datavis3d/engine/abstract3dcontroller_p.h | 39 +- src/datavis3d/engine/abstract3drenderer.cpp | 28 +- src/datavis3d/engine/abstract3drenderer_p.h | 15 +- src/datavis3d/engine/bars3dcontroller.cpp | 183 +-------- src/datavis3d/engine/bars3dcontroller_p.h | 20 - src/datavis3d/engine/bars3drenderer.cpp | 121 +++--- src/datavis3d/engine/bars3drenderer_p.h | 14 +- src/datavis3d/engine/drawer.cpp | 6 +- src/datavis3d/engine/drawer_p.h | 4 +- src/datavis3d/engine/engine.pri | 18 +- src/datavis3d/engine/q3dbox.cpp | 480 ++++++++++++++++++++++++ src/datavis3d/engine/q3dbox.h | 184 +++++++++ src/datavis3d/engine/q3dcamera.cpp | 295 +++++++++++++++ src/datavis3d/engine/q3dcamera.h | 87 +++++ src/datavis3d/engine/q3dcamera_p.h | 61 +++ src/datavis3d/engine/q3dlight.cpp | 49 +++ src/datavis3d/engine/q3dlight.h | 50 +++ src/datavis3d/engine/q3dlight_p.h | 57 +++ src/datavis3d/engine/q3dobject.cpp | 73 ++++ src/datavis3d/engine/q3dobject.h | 54 +++ src/datavis3d/engine/q3dobject_p.h | 53 +++ src/datavis3d/engine/q3dscene.cpp | 199 ++++++++++ src/datavis3d/engine/q3dscene.h | 83 ++++ src/datavis3d/engine/q3dscene_p.h | 60 +++ src/datavis3d/engine/scatter3dcontroller.cpp | 154 -------- src/datavis3d/engine/scatter3dcontroller_p.h | 23 -- src/datavis3d/engine/scatter3drenderer.cpp | 99 ++--- src/datavis3d/engine/scatter3drenderer_p.h | 9 +- src/datavis3d/engine/selectionpointer.cpp | 27 +- src/datavis3d/engine/selectionpointer_p.h | 7 +- src/datavis3d/engine/surface3dcontroller.cpp | 81 +--- src/datavis3d/engine/surface3dcontroller_p.h | 19 +- src/datavis3d/engine/surface3drenderer.cpp | 66 ++-- src/datavis3d/engine/surface3drenderer_p.h | 7 +- src/datavis3d/input/input.pri | 3 +- src/datavis3d/input/q3dinputhandler.cpp | 52 ++- src/datavis3d/input/q3dinputhandler.h | 15 +- src/datavis3d/input/q3dinputhandler_p.h | 51 +++ src/datavis3d/input/qabstract3dinputhandler.cpp | 64 ++-- src/datavis3d/input/qabstract3dinputhandler.h | 54 ++- src/datavis3d/input/qabstract3dinputhandler_p.h | 17 +- src/datavis3d/input/qtouch3dinputhandler.cpp | 31 +- src/datavis3d/input/qtouch3dinputhandler.h | 8 +- 44 files changed, 2439 insertions(+), 770 deletions(-) create mode 100644 src/datavis3d/engine/q3dbox.cpp create mode 100644 src/datavis3d/engine/q3dbox.h create mode 100644 src/datavis3d/engine/q3dcamera.cpp create mode 100644 src/datavis3d/engine/q3dcamera.h create mode 100644 src/datavis3d/engine/q3dcamera_p.h create mode 100644 src/datavis3d/engine/q3dlight.cpp create mode 100644 src/datavis3d/engine/q3dlight.h create mode 100644 src/datavis3d/engine/q3dlight_p.h create mode 100644 src/datavis3d/engine/q3dobject.cpp create mode 100644 src/datavis3d/engine/q3dobject.h create mode 100644 src/datavis3d/engine/q3dobject_p.h create mode 100644 src/datavis3d/engine/q3dscene.cpp create mode 100644 src/datavis3d/engine/q3dscene.h create mode 100644 src/datavis3d/engine/q3dscene_p.h create mode 100644 src/datavis3d/input/q3dinputhandler_p.h (limited to 'src') diff --git a/src/datavis3d/engine/abstract3dcontroller.cpp b/src/datavis3d/engine/abstract3dcontroller.cpp index 9b6040c1..fcc75915 100644 --- a/src/datavis3d/engine/abstract3dcontroller.cpp +++ b/src/datavis3d/engine/abstract3dcontroller.cpp @@ -22,7 +22,10 @@ #include "q3dvalueaxis.h" #include "q3dcategoryaxis.h" #include "abstract3drenderer_p.h" +#include "q3dcamera.h" +#include "q3dlight.h" #include "qabstractdataproxy_p.h" +#include "qabstract3dinputhandler.h" #if defined(Q_OS_ANDROID) #include "qtouch3dinputhandler.h" @@ -46,8 +49,8 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_labelTransparency(QDataVis::TransparencyNoBackground), m_isBackgroundEnabled(true), m_isGridEnabled(true), - m_cameraHelper(new CameraHelper()), - m_zoomLevel(100), + m_scene(new Q3DScene()), + m_activeInputHandler(0), m_axisX(0), m_axisY(0), m_axisZ(0), @@ -57,25 +60,31 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_renderPending(false) { m_theme.useColorTheme(QDataVis::ThemeSystem); + + // Populate the scene + m_scene->setCamera(new Q3DCamera()); + m_scene->setLight(new Q3DLight()); + m_scene->light()->setPosition(defaultLightPos); + + // Create initial default input handler + QAbstract3DInputHandler *inputHandler; #if defined(Q_OS_ANDROID) - m_inputHandler = new QTouch3DInputHandler(); + inputHandler = new QTouch3DInputHandler(); #else - m_inputHandler = new Q3DInputHandler(); + inputHandler = new Q3DInputHandler(); #endif - m_inputHandler->setCamera(m_cameraHelper); + inputHandler->d_ptr->m_isDefaultHandler = true; + setActiveInputHandler(inputHandler); } Abstract3DController::~Abstract3DController() { - delete m_cameraHelper; - delete m_inputHandler; - // Attached axes are children, so no need to explicitly delete them - // Renderer can be in another thread, don't delete it directly in that case if (m_renderer && m_renderer->thread() != QThread::currentThread()) m_renderer->deleteLater(); else delete m_renderer; + delete m_scene; } void Abstract3DController::setRenderer(Abstract3DRenderer *renderer) @@ -89,16 +98,13 @@ void Abstract3DController::synchDataToRenderer() if (!m_renderer) return; + m_renderer->updateScene(m_scene); + if (m_changeTracker.positionChanged) { m_renderer->updatePosition(m_boundingRect); m_changeTracker.positionChanged = false; } - if (m_changeTracker.zoomLevelChanged) { - m_renderer->updateZoomLevel(m_zoomLevel); - m_changeTracker.zoomLevelChanged = false; - } - if (m_changeTracker.themeChanged) { m_renderer->updateTheme(m_theme); m_changeTracker.themeChanged = false; @@ -306,7 +312,7 @@ void Abstract3DController::render(const GLuint defaultFboHandle) if (!m_renderer) return; - m_renderer->render(m_cameraHelper, defaultFboHandle); + m_renderer->render(defaultFboHandle); #ifdef DISPLAY_RENDER_SPEED // To get meaningful framerate, don't just do render on demand. @@ -314,10 +320,47 @@ void Abstract3DController::render(const GLuint defaultFboHandle) #endif } +void Abstract3DController::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_activeInputHandler->mouseDoubleClickEvent(event); + emitNeedRender(); +} + +void Abstract3DController::touchEvent(QTouchEvent *event) +{ + m_activeInputHandler->touchEvent(event); + emitNeedRender(); +} + +void Abstract3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) +{ + m_activeInputHandler->mousePressEvent(event, mousePos); + emitNeedRender(); +} + +void Abstract3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) +{ + m_activeInputHandler->mouseReleaseEvent(event, mousePos); + emitNeedRender(); +} + +void Abstract3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) +{ + m_activeInputHandler->mouseMoveEvent(event, mousePos); + emitNeedRender(); +} + +void Abstract3DController::wheelEvent(QWheelEvent *event) +{ + m_activeInputHandler->wheelEvent(event); + emitNeedRender(); +} + void Abstract3DController::setSize(const int width, const int height) { m_boundingRect.setWidth(width); m_boundingRect.setHeight(height); + m_scene->setViewportSize(width, height); m_changeTracker.boundingRectChanged = true; emitNeedRender(); @@ -336,6 +379,7 @@ const QRect Abstract3DController::boundingRect() void Abstract3DController::setBoundingRect(const QRect boundingRect) { m_boundingRect = boundingRect; + m_scene->setViewport(boundingRect); m_changeTracker.boundingRectChanged = true; emitNeedRender(); @@ -344,6 +388,7 @@ void Abstract3DController::setBoundingRect(const QRect boundingRect) void Abstract3DController::setWidth(const int width) { m_boundingRect.setWidth(width); + m_scene->setViewportSize(width, m_scene->viewport().height()); m_changeTracker.sizeChanged = true; emitNeedRender(); @@ -357,6 +402,7 @@ int Abstract3DController::width() void Abstract3DController::setHeight(const int height) { m_boundingRect.setHeight(height); + m_scene->setViewportSize(m_scene->viewport().width(), height); m_changeTracker.sizeChanged = true; emitNeedRender(); @@ -393,6 +439,26 @@ int Abstract3DController::y() return m_boundingRect.y(); } +QRect Abstract3DController::mainViewport() const +{ + return m_scene->mainViewport(); +} + +void Abstract3DController::setMainViewport(const QRect &mainViewport) +{ + m_scene->setMainViewport(mainViewport); +} + +QRect Abstract3DController::sliceViewport() const +{ + return m_scene->sliceViewport(); +} + +void Abstract3DController::setSliceViewport(const QRect &sliceViewport) +{ + m_scene->setSliceViewport(sliceViewport); +} + void Abstract3DController::setAxisX(Q3DAbstractAxis *axis) { setAxisHelper(Q3DAbstractAxis::AxisOrientationX, axis, &m_axisX); @@ -525,14 +591,68 @@ void Abstract3DController::setActiveDataProxy(QAbstractDataProxy *proxy) emitNeedRender(); } +void Abstract3DController::addInputHandler(QAbstract3DInputHandler *inputHandler) +{ + Q_ASSERT(inputHandler); + Abstract3DController *owner = qobject_cast(inputHandler->parent()); + if (owner != this) { + Q_ASSERT_X(!owner, "addInputHandler", "Input handler already attached to another component."); + inputHandler->setParent(this); + } + + if (!m_inputHandlers.contains(inputHandler)) + m_inputHandlers.append(inputHandler); +} + +void Abstract3DController::releaseInputHandler(QAbstract3DInputHandler *inputHandler) +{ + if (inputHandler && m_inputHandlers.contains(inputHandler)) { + // Clear the default status from released default input handler + if (inputHandler->d_ptr->m_isDefaultHandler) + inputHandler->d_ptr->m_isDefaultHandler = false; + + // If the input handler is in use, remove it + if (m_activeInputHandler == inputHandler) + setActiveInputHandler(0); + + m_inputHandlers.removeAll(inputHandler); + inputHandler->setParent(0); + } +} + +void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputHandler) +{ + // If existing input handler is the default input handler, delete it + if (m_activeInputHandler) { + if (m_activeInputHandler->d_ptr->m_isDefaultHandler) { + m_inputHandlers.removeAll(m_activeInputHandler); + delete m_activeInputHandler; + } else { + // Disconnect the old input handler from the scene + m_activeInputHandler->setScene(0); + } + } + + // Assume ownership and connect to this controller's scene + addInputHandler(inputHandler); + m_activeInputHandler = inputHandler; + if (m_activeInputHandler) + m_activeInputHandler->setScene(m_scene); +} + +QAbstract3DInputHandler* Abstract3DController::activeInputHandler() +{ + return m_activeInputHandler; +} + int Abstract3DController::zoomLevel() { - return m_zoomLevel; + return m_scene->camera()->zoomLevel(); } void Abstract3DController::setZoomLevel(int zoomLevel) { - m_zoomLevel = zoomLevel; + m_scene->camera()->setZoomLevel(zoomLevel); m_changeTracker.zoomLevelChanged = true; emitNeedRender(); @@ -540,7 +660,7 @@ void Abstract3DController::setZoomLevel(int zoomLevel) void Abstract3DController::setCameraPreset(QDataVis::CameraPreset preset) { - m_cameraHelper->setCameraPreset(preset); + m_scene->camera()->setCameraPreset(preset); emitNeedRender(); } @@ -548,10 +668,9 @@ void Abstract3DController::setCameraPosition(GLfloat horizontal, GLfloat vertica { m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f); m_verticalRotation = qBound(0.0f, vertical, 90.0f); - m_zoomLevel = qBound(10, distance, 500); - m_changeTracker.zoomLevelChanged = true; - m_cameraHelper->setCameraRotation(QPointF(m_horizontalRotation, - m_verticalRotation)); + m_scene->camera()->setZoomLevel(qBound(10, distance, 500)); + m_scene->camera()->setRotations(QPointF(m_horizontalRotation, + m_verticalRotation)); //qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation; emitNeedRender(); } @@ -657,6 +776,27 @@ bool Abstract3DController::gridEnabled() return m_isGridEnabled; } +bool Abstract3DController::isSlicingActive() +{ + return m_scene->isSlicingActivated(); +} + +void Abstract3DController::setSlicingActive(bool isSlicing) +{ + m_scene->setSlicingActivated(isSlicing); + emitNeedRender(); +} + +QDataVis::InputState Abstract3DController::inputState() +{ + return m_activeInputHandler->inputState(); +} + +QPoint Abstract3DController::inputPosition() +{ + return m_activeInputHandler->inputPosition(); +} + void Abstract3DController::setMeshFileName(const QString &fileName) { m_objFile = fileName; @@ -669,6 +809,11 @@ QString Abstract3DController::meshFileName() return m_objFile; } +Q3DScene *Abstract3DController::scene() +{ + return m_scene; +} + void Abstract3DController::handleAxisTitleChanged(const QString &title) { Q_UNUSED(title) diff --git a/src/datavis3d/engine/abstract3dcontroller_p.h b/src/datavis3d/engine/abstract3dcontroller_p.h index 83ea8379..ccc0cc40 100644 --- a/src/datavis3d/engine/abstract3dcontroller_p.h +++ b/src/datavis3d/engine/abstract3dcontroller_p.h @@ -37,6 +37,8 @@ #include "drawer_p.h" #include "qabstract3dinputhandler.h" #include "qabstractdataproxy.h" +#include "q3dscene.h" +#include "q3dbox.h" class QFont; @@ -153,10 +155,12 @@ private: bool m_isGridEnabled; QString m_objFile; + Q3DScene *m_scene; + protected: - QAbstract3DInputHandler *m_inputHandler; + QList m_inputHandlers; // List of all added input handlers + QAbstract3DInputHandler *m_activeInputHandler; CameraHelper *m_cameraHelper; - int m_zoomLevel; // Active axes Q3DAbstractAxis *m_axisX; Q3DAbstractAxis *m_axisY; @@ -204,6 +208,13 @@ public: virtual int x(); virtual void setY(const int y); virtual int y(); + + virtual QRect mainViewport() const; + virtual void setMainViewport(const QRect &mainViewport); + + virtual QRect sliceViewport() const; + virtual void setSliceViewport(const QRect &sliceViewport); + virtual void setAxisX(Q3DAbstractAxis *axis); virtual Q3DAbstractAxis *axisX(); virtual void setAxisY(Q3DAbstractAxis *axis); @@ -214,6 +225,11 @@ public: virtual void releaseAxis(Q3DAbstractAxis *axis); virtual QList axes() const; // Omits default axes + virtual void addInputHandler(QAbstract3DInputHandler *inputHandler); + virtual void releaseInputHandler(QAbstract3DInputHandler *inputHandler); + virtual void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); + virtual QAbstract3DInputHandler *activeInputHandler(); + virtual QAbstractDataProxy *activeDataProxy() const; virtual void addDataProxy(QAbstractDataProxy *proxy); virtual void releaseDataProxy(QAbstractDataProxy *proxy); @@ -265,10 +281,28 @@ public: virtual void setGridEnabled(bool enable); virtual bool gridEnabled(); + // Query input state and position + QDataVis::InputState inputState(); + QPoint inputPosition(); + + // Enable or disable slicing mode + bool isSlicingActive(); + void setSlicingActive(bool isSlicing); + + // override bar type with own mesh virtual void setMeshFileName(const QString &fileName); virtual QString meshFileName(); + Q3DScene *scene(); + + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void touchEvent(QTouchEvent *event); + virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); + virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); + virtual void wheelEvent(QWheelEvent *event); + virtual void handleAxisTitleChangedBySender(QObject *sender); virtual void handleAxisLabelsChangedBySender(QObject *sender); virtual void handleAxisRangeChangedBySender(QObject *sender); @@ -289,7 +323,6 @@ public slots: signals: void shadowQualityChanged(QDataVis::ShadowQuality quality); - void needRender(); protected: diff --git a/src/datavis3d/engine/abstract3drenderer.cpp b/src/datavis3d/engine/abstract3drenderer.cpp index c3cc7b7e..9f64157a 100644 --- a/src/datavis3d/engine/abstract3drenderer.cpp +++ b/src/datavis3d/engine/abstract3drenderer.cpp @@ -20,6 +20,8 @@ #include "q3dvalueaxis.h" #include "texturehelper_p.h" #include "utils_p.h" +#include "q3dscene.h" +#include "q3dcamera.h" QT_DATAVIS3D_BEGIN_NAMESPACE @@ -34,10 +36,10 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_cachedBoundingRect(QRect(0,0,0,0)), m_cachedShadowQuality(QDataVis::ShadowMedium), m_autoScaleAdjustment(1.0f), - m_cachedZoomLevel(100), m_cachedSelectionMode(QDataVis::ModeNone), m_cachedIsGridEnabled(false), - m_cachedIsBackgroundEnabled(false) + m_cachedIsBackgroundEnabled(false), + m_cachedScene(0) #ifdef DISPLAY_RENDER_SPEED , m_isFirstFrame(true), m_numFrames(0) @@ -51,6 +53,7 @@ Abstract3DRenderer::~Abstract3DRenderer() { delete m_drawer; delete m_textureHelper; + delete m_cachedScene; } void Abstract3DRenderer::initializeOpenGL() @@ -75,10 +78,8 @@ void Abstract3DRenderer::initializeOpenGL() axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationZ).setDrawer(m_drawer); } -void Abstract3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) +void Abstract3DRenderer::render(const GLuint defaultFboHandle) { - Q_UNUSED(camera) - #ifdef DISPLAY_RENDER_SPEED // For speed computation if (m_isFirstFrame) { @@ -127,13 +128,13 @@ QString Abstract3DRenderer::itemLabelFormat() const return m_cachedItemLabelFormat; } -void Abstract3DRenderer::updateBoundingRect(const QRect boundingRect) +void Abstract3DRenderer::updateBoundingRect(const QRect &boundingRect) { m_cachedBoundingRect = boundingRect; handleResize(); } -void Abstract3DRenderer::updatePosition(const QRect boundingRect) +void Abstract3DRenderer::updatePosition(const QRect &boundingRect) { m_cachedBoundingRect = boundingRect; } @@ -147,6 +148,14 @@ void Abstract3DRenderer::updateTheme(Theme theme) handleShadowQualityChange(); } +void Abstract3DRenderer::updateScene(Q3DScene *scene) +{ + // Make a copy of the scene to renderer's cache. + Q3DScene *newScene = scene->clone(); + delete m_cachedScene; + m_cachedScene = newScene; +} + void Abstract3DRenderer::handleShadowQualityChange() { #if !defined(QT_OPENGL_ES_2) @@ -242,11 +251,6 @@ void Abstract3DRenderer::handleResize() #endif } -void Abstract3DRenderer::updateZoomLevel(int newZoomLevel) -{ - m_cachedZoomLevel = newZoomLevel; -} - void Abstract3DRenderer::updateAxisType(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis::AxisType type) { axisCacheForOrientation(orientation).setType(type); diff --git a/src/datavis3d/engine/abstract3drenderer_p.h b/src/datavis3d/engine/abstract3drenderer_p.h index 0da11ff1..7f58f59c 100644 --- a/src/datavis3d/engine/abstract3drenderer_p.h +++ b/src/datavis3d/engine/abstract3drenderer_p.h @@ -62,7 +62,6 @@ protected: QRect m_cachedBoundingRect; QDataVis::ShadowQuality m_cachedShadowQuality; GLfloat m_autoScaleAdjustment; - int m_cachedZoomLevel; QString m_cachedItemLabelFormat; QString m_cachedObjFile; @@ -70,11 +69,13 @@ protected: bool m_cachedIsGridEnabled; bool m_cachedIsBackgroundEnabled; - AxisRenderCache m_axisCacheX; AxisRenderCache m_axisCacheY; AxisRenderCache m_axisCacheZ; TextureHelper *m_textureHelper; + Q3DBox m_boundingBox; + + Q3DScene *m_cachedScene; #ifdef DISPLAY_RENDER_SPEED bool m_isFirstFrame; @@ -89,12 +90,11 @@ public: void updateDataModel(QAbstractDataProxy *dataProxy); - virtual void render(CameraHelper *camera, const GLuint defaultFboHandle); + virtual void render(GLuint defaultFboHandle); - virtual void updateBoundingRect(const QRect boundingRect); - virtual void updatePosition(const QRect boundingRect); + virtual void updateBoundingRect(const QRect &boundingRect); + virtual void updatePosition(const QRect &boundingRect); - virtual void updateZoomLevel(int newZoomLevel); virtual void updateTheme(Theme theme); virtual void updateFont(const QFont &font); virtual void updateLabelTransparency(QDataVis::LabelTransparency transparency); @@ -102,10 +102,11 @@ public: virtual void updateGridEnabled(bool enable); virtual void updateBackgroundEnabled(bool enable); virtual void updateMeshFileName(const QString &objFileName); - + virtual void updateScene(Q3DScene *scene); virtual QString itemLabelFormat() const; virtual void updateTextures() = 0; virtual void initSelectionBuffer() = 0; + #if !defined(QT_OPENGL_ES_2) virtual void updateDepthBuffer() = 0; #endif diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp index 1591eb46..0febdb68 100644 --- a/src/datavis3d/engine/bars3dcontroller.cpp +++ b/src/datavis3d/engine/bars3dcontroller.cpp @@ -34,9 +34,6 @@ Bars3DController::Bars3DController(QRect boundRect) : Abstract3DController(boundRect), m_rowCount(10), m_columnCount(10), - m_mouseState(MouseNone), - m_mousePos(QPoint(0, 0)), - m_isSlicingActivated(false), m_selectedBarPos(noSelectionPoint()), m_isBarSpecRelative(true), m_barThicknessRatio(1.0f), @@ -67,6 +64,7 @@ void Bars3DController::initializeOpenGL() return; m_renderer = new Bars3DRenderer(this); + setRenderer(m_renderer); synchDataToRenderer(); @@ -83,11 +81,6 @@ void Bars3DController::synchDataToRenderer() return; // Notify changes to renderer - if (m_changeTracker.slicingActiveChanged) { - m_renderer->updateSlicingActive(m_isSlicingActivated); - m_changeTracker.slicingActiveChanged = false; - } - if (m_changeTracker.sampleSpaceChanged) { m_renderer->updateSampleSpace(m_rowCount, m_columnCount); m_changeTracker.sampleSpaceChanged = false; @@ -109,159 +102,6 @@ void Bars3DController::synchDataToRenderer() } } -QMatrix4x4 Bars3DController::calculateViewMatrix(int zoom, int viewPortWidth, - int viewPortHeight, bool showUnder) -{ - return m_cameraHelper->calculateViewMatrix(m_mousePos, - zoom, - viewPortWidth, - viewPortHeight, - showUnder); -} - -bool Bars3DController::isSlicingActive() -{ - return m_isSlicingActivated; -} - -void Bars3DController::setSlicingActive(bool isSlicing) -{ - m_isSlicingActivated = isSlicing; - - m_changeTracker.slicingActiveChanged = true; - emitNeedRender(); -} - -Bars3DController::MouseState Bars3DController::mouseState() -{ - return m_mouseState; -} - - -#if defined(Q_OS_ANDROID) -void Bars3DController::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (!m_isSlicingActivated) { - m_mouseState = Bars3DController::MouseOnScene; - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = event->pos(); - emitNeedRender(); - } -} - -void Bars3DController::touchEvent(QTouchEvent *event) -{ - static int prevDistance = 0; - - QList points; - points = event->touchPoints(); - - if (!m_isSlicingActivated && points.count() == 2) { - m_mouseState = Bars3DController::MouseOnPinch; - - QPointF distance = points.at(0).pos() - points.at(1).pos(); - int newDistance = distance.manhattanLength(); - int zoomRate = 1; - int zoomLevel = m_zoomLevel; - if (zoomLevel > 100) - zoomRate = 5; - if (newDistance > prevDistance) - zoomLevel += zoomRate; - else - zoomLevel -= zoomRate; - if (zoomLevel > 500) - zoomLevel = 500; - else if (zoomLevel < 10) - zoomLevel = 10; - setZoomLevel(zoomLevel); - prevDistance = newDistance; - //qDebug() << "distance" << distance.manhattanLength(); - } -} -#endif - -void Bars3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) -{ - QRect mainViewPort = m_renderer->mainViewPort(); - if (Qt::LeftButton == event->button()) { - if (m_isSlicingActivated) { - if (mousePos.x() <= mainViewPort.width() - && mousePos.y() <= mainViewPort.height()) { - m_mouseState = Bars3DController::MouseOnOverview; - //qDebug() << "Mouse pressed on overview"; - } else { - m_mouseState = Bars3DController::MouseOnZoom; - //qDebug() << "Mouse pressed on zoom"; - } - } else { -#if !defined(Q_OS_ANDROID) - m_mouseState = Bars3DController::MouseOnScene; -#else - m_mouseState = Bars3DController::MouseRotating; -#endif - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - //qDebug() << "Mouse pressed on scene"; - } - } else if (Qt::MiddleButton == event->button()) { - // reset rotations - m_mousePos = QPoint(0, 0); - } else if (!m_isSlicingActivated && Qt::RightButton == event->button()) { - // disable rotating when in slice view -#if !defined(Q_OS_ANDROID) - m_mouseState = Bars3DController::MouseRotating; -#else - m_mouseState = Bars3DController::MouseOnScene; -#endif - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - } - m_cameraHelper->updateMousePos(m_mousePos); - emitNeedRender(); -} - -void Bars3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event); - if (Bars3DController::MouseRotating == m_mouseState) { - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - m_cameraHelper->updateMousePos(mousePos); - emitNeedRender(); - } - m_mouseState = Bars3DController::MouseNone; -} - -void Bars3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event); - if (Bars3DController::MouseRotating == m_mouseState) { - m_mousePos = mousePos; - emitNeedRender(); - } -} - -void Bars3DController::wheelEvent(QWheelEvent *event) -{ - // disable zooming if in slice view - if (m_isSlicingActivated) - return; - - int zoomLevel = m_zoomLevel; - if (zoomLevel > 100) - zoomLevel += event->angleDelta().y() / 12; - else if (zoomLevel > 50) - zoomLevel += event->angleDelta().y() / 60; - else - zoomLevel += event->angleDelta().y() / 120; - if (zoomLevel > 500) - zoomLevel = 500; - else if (zoomLevel < 10) - zoomLevel = 10; - - setZoomLevel(zoomLevel); -} - void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy) { // Setting null proxy indicates default proxy @@ -297,7 +137,7 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy) void Bars3DController::handleArrayReset() { - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; // Clear selection unless still valid @@ -311,7 +151,7 @@ void Bars3DController::handleRowsAdded(int startIndex, int count) Q_UNUSED(count) // TODO check if affects data window // TODO should update slice instead of deactivating? - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; emitNeedRender(); @@ -323,7 +163,7 @@ void Bars3DController::handleRowsChanged(int startIndex, int count) Q_UNUSED(count) // TODO check if affects data window // TODO should update slice instead of deactivating? - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; emitNeedRender(); @@ -335,7 +175,7 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count) Q_UNUSED(count) // TODO check if affects data window // TODO should update slice instead of deactivating? - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; @@ -351,7 +191,7 @@ void Bars3DController::handleRowsInserted(int startIndex, int count) Q_UNUSED(count) // TODO check if affects data window // TODO should update slice instead of deactivating? - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; emitNeedRender(); @@ -363,7 +203,7 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) Q_UNUSED(columnIndex) // TODO check if affects data window // TODO should update slice instead of deactivating? - setSlicingActive(false); + scene()->setSlicingActivated(false); adjustValueAxisRange(); m_isDataDirty = true; emitNeedRender(); @@ -444,7 +284,7 @@ void Bars3DController::setBarType(QDataVis::MeshStyle style, bool smooth) void Bars3DController::setDataWindow(int rowCount, int columnCount) { // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted) - setSlicingActive(false); + scene()->setSlicingActivated(false); m_rowCount = rowCount; m_columnCount = columnCount; @@ -462,7 +302,7 @@ void Bars3DController::setDataWindow(int rowCount, int columnCount) void Bars3DController::setSelectionMode(QDataVis::SelectionMode mode) { // Disable zoom if selection mode changes - setSlicingActive(false); + scene()->setSlicingActivated(false); Abstract3DController::setSelectionMode(mode); } @@ -492,11 +332,6 @@ QPoint Bars3DController::selectedBarPos() const return m_selectedBarPos; } -QPoint Bars3DController::mousePosition() -{ - return m_mousePos; -} - int Bars3DController::columnCount() { return m_columnCount; diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h index fff153cf..bfc35636 100644 --- a/src/datavis3d/engine/bars3dcontroller_p.h +++ b/src/datavis3d/engine/bars3dcontroller_p.h @@ -66,9 +66,6 @@ private: int m_columnCount; // Interaction - MouseState m_mouseState; - QPoint m_mousePos; - bool m_isSlicingActivated; QPoint m_selectedBarPos; // Points to row & column in data window. // Look'n'feel @@ -89,14 +86,6 @@ public: int columnCount(); int rowCount(); - MouseState mouseState(); - QPoint mousePosition(); - - bool isSlicingActive(); - void setSlicingActive(bool isSlicing); - - QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder = false); - // bar thickness, spacing between bars, and is spacing relative to thickness or absolute // y -component sets the thickness/spacing of z -direction // With relative 0.0f means side-to-side, 1.0f = one thickness in between @@ -119,15 +108,6 @@ public: void setSelectedBarPos(const QPoint &position); QPoint selectedBarPos() const; -#if defined(Q_OS_ANDROID) - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); -#endif - void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); - void wheelEvent(QWheelEvent *event); - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp index 260b36a2..5a5a659a 100644 --- a/src/datavis3d/engine/bars3drenderer.cpp +++ b/src/datavis3d/engine/bars3drenderer.cpp @@ -18,7 +18,7 @@ #include "bars3drenderer_p.h" #include "bars3dcontroller_p.h" -#include "camerahelper_p.h" +#include "q3dcamera.h" #include "shaderhelper_p.h" #include "objecthelper_p.h" #include "texturehelper_p.h" @@ -26,6 +26,7 @@ #include "utils_p.h" #include "drawer_p.h" #include "qbardataitem.h" +#include "q3dlight.h" #include #include @@ -173,29 +174,43 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) Abstract3DRenderer::updateDataModel(dataProxy); } -void Bars3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) +void Bars3DRenderer::updateScene(Q3DScene *scene) { - // Handle GL state setup for FBO buffers and clearing of the render surface - Abstract3DRenderer::render(camera, defaultFboHandle); - + // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. + scene->setSliceViewport(m_sliceViewPort); + scene->setMainViewport(m_mainViewPort); + scene->setUnderSideCameraEnabled(m_hasNegativeValues); if (m_hasHeightAdjustmentChanged) { // Set initial camera position. Also update if height adjustment has changed. - camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), - QVector3D(0.0f, -m_yAdjustment, zComp), - QVector3D(0.0f, 1.0f, 0.0f)); + scene->camera()->setDefaultOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), + QVector3D(0.0f, -m_yAdjustment, zComp), + QVector3D(0.0f, 1.0f, 0.0f)); m_hasHeightAdjustmentChanged = false; } + scene->camera()->updateViewMatrix(m_autoScaleAdjustment); + // Set light position (rotate light with camera, a bit above it (as set in defaultLightPos)) + scene->setLightPositionRelativeToCamera(defaultLightPos); + + Abstract3DRenderer::updateScene(scene); +} + +void Bars3DRenderer::render(GLuint defaultFboHandle) +{ + updateSlicingActive(m_cachedScene->isSlicingActivated()); + + // Handle GL state setup for FBO buffers and clearing of the render surface + Abstract3DRenderer::render(defaultFboHandle); + // If slice selection is on, draw the sliced scene if (m_cachedIsSlicingActivated) - drawSlicedScene(camera, m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem()); + drawSlicedScene(m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem()); // Draw bars scene - drawScene(camera, defaultFboHandle); + drawScene(defaultFboHandle); } -void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, - const LabelItem &xLabel, +void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel) { @@ -215,13 +230,8 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, / (GLfloat)m_sliceViewPort.height(), 0.1f, 100.0f); #ifdef ROTATE_ZOOM_SELECTION - // Calculate view matrix - QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix(m_cachedZoomLevel * m_autoScaleAdjustment, - m_sliceViewPort.width(), - m_sliceViewPort.height()); - // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos)) - lightPos = camera->calculateLightPosition(defaultLightPos); + lightPos = m_cachedScene->light()->position(); if (viewMatrix.row(0).z() <= 0) { startBar = m_sliceSelection->size() - 1; @@ -233,9 +243,9 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, QMatrix4x4 viewMatrix; // Adjust scaling (zoom rate based on aspect ratio) - GLfloat camPosZoomed = 5.0f / m_autoScaleAdjustment + zComp; + GLfloat camZPosSliced = 5.0f / m_autoScaleAdjustment + zComp; - viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camPosZoomed), + viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camZPosSliced), QVector3D(0.0f, 0.0f, zComp), QVector3D(0.0f, 1.0f, 0.0f)); @@ -322,32 +332,32 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelTop); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelTop); } m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelBottom); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelBottom); } else { m_drawer->drawLabel(*dummyItem, xLabel, viewMatrix, projectionMatrix, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelBottom); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelBottom); if (m_sliceTitleItem) { m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelTop); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelTop); } } m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 90.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelLeft); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelLeft); // Draw labels for bars for (int col = 0; col < m_sliceSelection->size(); col++) { @@ -357,7 +367,7 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), item->height(), m_cachedSelectionMode, m_labelShader, - m_labelObj, camera); + m_labelObj, m_cachedScene->camera()); // Draw labels if (m_sliceCache->labelItems().size() > col) { @@ -373,7 +383,7 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, -45.0f), item->height(), m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, false, false, Drawer::LabelBelow); + m_labelObj, m_cachedScene->camera(), false, false, Drawer::LabelBelow); } } @@ -386,8 +396,7 @@ void Bars3DRenderer::drawSlicedScene(CameraHelper *camera, m_labelShader->release(); } -void Bars3DRenderer::drawScene(CameraHelper *camera, - const GLuint defaultFboHandle) +void Bars3DRenderer::drawScene(GLuint defaultFboHandle) { GLint startBar = 0; GLint stopBar = 0; @@ -413,12 +422,8 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f); - // Calculate view matrix - QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - m_cachedZoomLevel * m_autoScaleAdjustment, - m_mainViewPort.width(), - m_mainViewPort.height(), - m_hasNegativeValues); + // Get the view matrix + QMatrix4x4 viewMatrix = m_cachedScene->camera()->viewMatrix(); // Calculate drawing order // Draw order is reversed to optimize amount of drawing (ie. draw front objects first, depth test handles not needing to draw objects behind them) @@ -461,8 +466,8 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() <= 0) backgroundRotation = 0.0f; - // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos)) - QVector3D lightPos = camera->calculateLightPosition(defaultLightPos); + // Get light position from the scene + QVector3D lightPos = m_cachedScene->light()->position(); // Skip depth rendering if we're in slice mode // TODO: Fix this, causes problems if depth rendering is off in slice mode @@ -487,12 +492,14 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, // Get the depth view matrix // It may be possible to hack lightPos here if we want to make some tweaks to shadow - QVector3D depthLightPos = camera->calculateLightPosition( + QVector3D depthLightPos = m_cachedScene->camera()->calculatePositionRelativeToCamera( QVector3D(0.0f, 0.0f, zComp), 0.0f, 1.5f / m_autoScaleAdjustment); depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, -m_yAdjustment, zComp), QVector3D(0.0f, 1.0f, 0.0f)); - // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed - //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); + + // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? + // That causes the scene to be not drawn from above -> must be fixed + // qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); // Set the depth projection matrix #ifndef USE_WIDER_SHADOWS // Use this for perspective shadows @@ -662,8 +669,10 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, glEnable(GL_DITHER); // Read color under cursor - if (Bars3DController::MouseOnScene == m_controller->mouseState()) - m_selection = Utils::getSelection(m_controller->mousePosition(), m_cachedBoundingRect.height()); + if (QDataVis::InputOnScene == m_controller->inputState()) { + m_selection = Utils::getSelection(m_controller->inputPosition(), + m_cachedBoundingRect.height()); + } glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -697,7 +706,7 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, bool selectionDirty = (m_selection != m_previousSelection || (m_selection != selectionSkipColor - && Bars3DController::MouseOnScene == m_controller->mouseState() + && QDataVis::InputOnScene == m_controller->inputState() && !m_cachedIsSlicingActivated)); if (selectionDirty) { m_previousSelection = m_selection; @@ -1214,10 +1223,9 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } - } for (int column = 0; column != m_cachedColumnCount; column += 1) { if (m_axisCacheZ.labelItems().size() > column) { @@ -1253,7 +1261,7 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } } @@ -1302,7 +1310,7 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); // Side wall @@ -1323,7 +1331,7 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } labelNbr++; @@ -1336,11 +1344,11 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, m_selectedBar = NULL; if (m_cachedIsSlicingActivated && (m_selection == selectionSkipColor - || Bars3DController::MouseOnOverview == m_controller->mouseState())) - m_controller->setSlicingActive(false); + || QDataVis::InputOnOverview == m_controller->inputState())) + m_cachedScene->setSlicingActivated(false); } else if (m_cachedSelectionMode >= QDataVis::ModeSliceRow && selectionDirty) { // Activate slice mode - m_controller->setSlicingActive(true); + m_cachedScene->setSlicingActivated(true); // Create label textures for (int col = 0; col < m_sliceSelection->size(); col++) { @@ -1403,7 +1411,7 @@ void Bars3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, m_yAdjustment, zComp), QVector3D(0.0f, 0.0f, 0.0f), selectedBar->height(), m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, true, false); + m_labelObj, m_cachedScene->camera(), true, false); // Reset label update flag; they should have been updated when we get here m_updateLabels = false; @@ -1438,7 +1446,7 @@ void Bars3DRenderer::handleResize() Abstract3DRenderer::handleResize(); } -void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, QSizeF spacing, bool relative) +void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative) { // Convert ratio to QSizeF, as we need it in that format for autoscaling calculations m_cachedBarThickness.setWidth(1.0f); @@ -1459,12 +1467,12 @@ void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientatio { Abstract3DRenderer::updateAxisRange(orientation, min, max); calculateHeightAdjustment(); - // Check if we have negative values if (min < 0 && !m_hasNegativeValues) { m_hasNegativeValues = true; // Reload background loadBackgroundMesh(); + } else if (min >= 0 && m_hasNegativeValues) { m_hasNegativeValues = false; // Reload background @@ -1523,7 +1531,7 @@ void Bars3DRenderer::updateBackgroundEnabled(bool enable) } } -void Bars3DRenderer::updateSelectedBarPos(QPoint position) +void Bars3DRenderer::updateSelectedBarPos(const QPoint &position) { if (position == Bars3DController::noSelectionPoint()) m_selection = selectionSkipColor; @@ -1683,6 +1691,9 @@ Bars3DController::SelectionType Bars3DRenderer::isSelected(GLint row, GLint bar) void Bars3DRenderer::updateSlicingActive(bool isSlicing) { + if (isSlicing == m_cachedIsSlicingActivated) + return; + m_cachedIsSlicingActivated = isSlicing; if (isSlicing) { m_mainViewPort = QRect(0, m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / 5, diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavis3d/engine/bars3drenderer_p.h index 777e22ee..99734315 100644 --- a/src/datavis3d/engine/bars3drenderer_p.h +++ b/src/datavis3d/engine/bars3drenderer_p.h @@ -44,7 +44,7 @@ QT_DATAVIS3D_BEGIN_NAMESPACE class ShaderHelper; class ObjectHelper; class LabelItem; -class CameraHelper; +class Q3DScene; class QT_DATAVIS3D_EXPORT Bars3DRenderer : public Abstract3DRenderer { @@ -111,7 +111,8 @@ public: ~Bars3DRenderer(); void updateDataModel(QBarDataProxy *dataProxy); - void render(CameraHelper *camera, const GLuint defaultFboHandle = 0); + void updateScene(Q3DScene *scene); + void render(GLuint defaultFboHandle = 0); QRect mainViewPort(); @@ -121,13 +122,13 @@ protected: public slots: void updateBarSpecs(GLfloat thicknessRatio = 1.0f, - QSizeF spacing = QSizeF(1.0, 1.0), + const QSizeF &spacing = QSizeF(1.0, 1.0), bool relative = true); void updateSelectionMode(QDataVis::SelectionMode newMode); void updateSlicingActive(bool isSlicing); void updateSampleSpace(int rowCount, int columnCount); void updateBackgroundEnabled(bool enable); - void updateSelectedBarPos(QPoint position); + void updateSelectedBarPos(const QPoint &position); // Overloaded from abstract renderer virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max); @@ -140,9 +141,8 @@ private: virtual void updateShadowQuality(QDataVis::ShadowQuality quality); virtual void updateTextures(); - void drawSlicedScene(CameraHelper *camera, - const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel); - void drawScene(CameraHelper *camera, const GLuint defaultFboHandle); + void drawSlicedScene(const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel); + void drawScene(GLuint defaultFboHandle); void handleResize(); void loadBackgroundMesh(); diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavis3d/engine/drawer.cpp index 284d5675..aa16205f 100644 --- a/src/datavis3d/engine/drawer.cpp +++ b/src/datavis3d/engine/drawer.cpp @@ -22,7 +22,7 @@ #include "objecthelper_p.h" #include "abstractobjecthelper_p.h" #include "surfaceobject_p.h" -#include "camerahelper_p.h" +#include "q3dcamera.h" #include "utils_p.h" #include "texturehelper_p.h" #include @@ -181,7 +181,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight, QDataVis::SelectionMode mode, ShaderHelper *shader, ObjectHelper *object, - CameraHelper *camera, + const Q3DCamera *camera, bool useDepth, bool rotateAlong, LabelPosition position, Qt::AlignmentFlag alignment) { @@ -296,7 +296,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte if (useDepth && !rotateAlong) { // Apply negative camera rotations to keep labels facing camera - QPointF camRotations = camera->getCameraRotations(); + QPointF camRotations = camera->rotations(); modelMatrix.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f); modelMatrix.rotate(-camRotations.y(), 1.0f, 0.0f, 0.0f); } diff --git a/src/datavis3d/engine/drawer_p.h b/src/datavis3d/engine/drawer_p.h index 82b3b6cf..3654dcc1 100644 --- a/src/datavis3d/engine/drawer_p.h +++ b/src/datavis3d/engine/drawer_p.h @@ -43,7 +43,7 @@ class ObjectHelper; class AbstractObjectHelper; class SurfaceObject; class TextureHelper; -class CameraHelper; +class Q3DCamera; class Drawer : public QObject, public QOpenGLFunctions { @@ -80,7 +80,7 @@ public: const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight, QDataVis::SelectionMode mode, ShaderHelper *shader, ObjectHelper *object, - CameraHelper *camera, + const Q3DCamera *camera, bool useDepth = false, bool rotateAlong = false, LabelPosition position = LabelOver, Qt::AlignmentFlag alignment = Qt::AlignCenter); diff --git a/src/datavis3d/engine/engine.pri b/src/datavis3d/engine/engine.pri index ddc5abd1..4c905fe9 100644 --- a/src/datavis3d/engine/engine.pri +++ b/src/datavis3d/engine/engine.pri @@ -17,7 +17,16 @@ HEADERS += $$PWD/q3dwindow_p.h \ $$PWD/scatter3drenderer_p.h \ $$PWD/axisrendercache_p.h \ $$PWD/abstract3drenderer_p.h \ - $$PWD/selectionpointer_p.h + $$PWD/selectionpointer_p.h \ + $$PWD/q3dcamera.h \ + $$PWD/q3dcamera_p.h \ + $$PWD/q3dscene.h \ + $$PWD/q3dlight.h \ + $$PWD/q3dlight_p.h \ + $$PWD/q3dbox.h \ + $$PWD/q3dobject.h \ + $$PWD/q3dobject_p.h \ + $$PWD/q3dscene_p.h SOURCES += $$PWD/q3dwindow.cpp \ $$PWD/q3dbars.cpp \ @@ -34,6 +43,11 @@ SOURCES += $$PWD/q3dwindow.cpp \ $$PWD/scatter3drenderer.cpp \ $$PWD/axisrendercache.cpp \ $$PWD/abstract3drenderer.cpp \ - $$PWD/selectionpointer.cpp + $$PWD/selectionpointer.cpp \ + $$PWD/q3dcamera.cpp \ + $$PWD/q3dlight.cpp \ + $$PWD/q3dbox.cpp \ + $$PWD/q3dobject.cpp \ + $$PWD/q3dscene.cpp RESOURCES += engine/engine.qrc diff --git a/src/datavis3d/engine/q3dbox.cpp b/src/datavis3d/engine/q3dbox.cpp new file mode 100644 index 00000000..cb250a2b --- /dev/null +++ b/src/datavis3d/engine/q3dbox.cpp @@ -0,0 +1,480 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "datavis3dglobal_p.h" +#include "q3dbox.h" +#include +#include + +QT_DATAVIS3D_BEGIN_NAMESPACE + +/*! + \class Q3DBox + \brief The Q3DBox class represents an axis-aligned box in 3D space. + + Q3DBox can be used to represent the bounding box of objects in a 3D + scene so that they can be easily culled if they are out of view. + + The sides of the box are always aligned with the x, y, and z axes of + the world co-ordinate system. Transforming a box with transformed() + will result in the smallest axis-aligned bounding box that contains + the transformed box. + + Boxes may be null, finite, or infinite. A null box does not occupy + any space and does not intersect with any other box. A finite + box consists of a minimum() and maximum() extent in 3D space. + An infinite box encompasses all points in 3D space. + + The extents of a finite box are also included within the box. + A box with minimum() and maximum() set to the same value + contains a single point. +*/ + +/*! + \fn Q3DBox::Q3DBox() + + Constructs a null box in 3D space. + + \sa isNull() +*/ + +/*! + \fn Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2) + + Constructs a finite box in 3D space from \a corner1 to \a corner2. + The minimum() and maximum() co-ordinates of the new box are set + to the minimum and maximum x, y, and z values from \a corner1 and + \a corner2. The \a corner1 and \a corner2 values can be any two + opposite corners that define the box. + + \sa isFinite(), minimum(), maximum() +*/ + +/*! + \fn bool Q3DBox::isNull() const + + Returns true if this box is null; false otherwise. + + \sa isFinite(), isInfinite(), setToNull() +*/ + +/*! + \fn bool Q3DBox::isFinite() const + + Returns true if this box is finite in size; false otherwise. + + \sa isNull(), isInfinite(), setExtents() +*/ + +/*! + \fn bool Q3DBox::isInfinite() const + + Returns true if this box is infinite in size; false otherwise. + + \sa isNull(), isFinite(), setToInfinite() +*/ + +/*! + \fn QVector3D Q3DBox::minimum() const + + Returns the minimum corner of this box. + + \sa maximum(), setExtents() +*/ + +/*! + \fn QVector3D Q3DBox::maximum() const + + Returns the maximum corner of this box. + + \sa minimum(), setExtents() +*/ + +/*! + \fn void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2) + + Sets the extents of this box to a finite region from \a corner1 to + \a corner2. The minimum() and maximum() co-ordinates of the box are + set to the minimum and maximum x, y, and z values from \a corner1 and + \a corner2. The \a corner1 and \a corner2 values can be any two + opposite corners that define the box. + + \sa minimum(), maximum() +*/ + +/*! + \fn void Q3DBox::setToNull() + + Sets this box to null. + + \sa isNull() +*/ + +/*! + \fn void Q3DBox::setToInfinite() + + Sets this box to be infinite in size. + + \sa isInfinite() +*/ + +/*! + \fn QVector3D Q3DBox::size() const + + Returns the finite size of this box. If this box is null or + infinite, the returned value will be zero. + + \sa center(), isNull(), isInfinite() +*/ + +/*! + \fn QVector3D Q3DBox::center() const + + Returns the finite center of this box. If this box is null + or infinite, the returned value will be zero. + + \sa size(), isNull(), isInfinite() +*/ + +/*! + \fn bool Q3DBox::contains(const QVector3D& point) const + + Returns true if this box contains \a point; false otherwise. + Null boxes do not contain any points and infinite boxes contain + all points. + + Containment is not a strict test: the point is contained if it + lies on one of the faces of the box. + + \sa intersects() +*/ + +/*! + \fn bool Q3DBox::contains(const Q3DBox& box) const + + Returns true if this box completely contains \a box. If this box + is null, then it will not contain \a box. If this box is infinite, + and \a box is not null, then \a box will be contained within this box. + If \a box is infinite, then this box must also be infinite to contain it. + + \sa intersects() +*/ + +/*! + Returns true if \a box intersects this box; false otherwise. + + \sa intersect(), intersected(), contains() +*/ +bool Q3DBox::intersects(const Q3DBox& box) const +{ + if (boxtype == Null) + return false; + else if (boxtype == Infinite) + return box.boxtype != Null; + else if (box.boxtype == Null) + return false; + else if (box.boxtype == Infinite) + return true; + + if (maxcorner.x() < box.mincorner.x()) + return false; + if (mincorner.x() > box.maxcorner.x()) + return false; + + if (maxcorner.y() < box.mincorner.y()) + return false; + if (mincorner.y() > box.maxcorner.y()) + return false; + + if (maxcorner.z() < box.mincorner.z()) + return false; + if (mincorner.z() > box.maxcorner.z()) + return false; + + return true; +} + +/*! + Intersects this box with \a box. + + \sa intersected(), intersects(), unite() +*/ +void Q3DBox::intersect(const Q3DBox& box) +{ + // Handle the simple cases first. + if (boxtype == Null) { + // Null intersected with anything is null. + return; + } else if (boxtype == Infinite) { + // Infinity intersected with a box is that box. + *this = box; + return; + } else if (box.boxtype == Null) { + // Anything intersected with null is null. + setToNull(); + return; + } else if (box.boxtype == Infinite) { + // Box intersected with infinity is the box. + return; + } + + // Intersect two finite boxes. + QVector3D min1 = mincorner; + QVector3D max1 = maxcorner; + QVector3D min2 = box.mincorner; + QVector3D max2 = box.maxcorner; + if (min2.x() > min1.x()) + min1.setX(min2.x()); + if (min2.y() > min1.y()) + min1.setY(min2.y()); + if (min2.z() > min1.z()) + min1.setZ(min2.z()); + if (max2.x() < max1.x()) + max1.setX(max2.x()); + if (max2.y() < max1.y()) + max1.setY(max2.y()); + if (max2.z() < max1.z()) + max1.setZ(max2.z()); + if (min1.x() > max1.x() || min1.y() > max1.y() || min1.z() > max1.z()) { + setToNull(); + } else { + mincorner = min1; + maxcorner = max1; + } +} + +/*! + Returns a new box which is the intersection of this box with \a box. + + \sa intersect(), intersects(), united() +*/ +Q3DBox Q3DBox::intersected(const Q3DBox& box) const +{ + Q3DBox result(*this); + result.intersect(box); + return result; +} + +/*! + Unites this box with \a point by expanding it to encompass \a point. + If \a point is already contained within this box, then this box + will be unchanged. + + \sa united(), intersect() +*/ +void Q3DBox::unite(const QVector3D& point) +{ + if (boxtype == Finite) { + if (point.x() < mincorner.x()) + mincorner.setX(point.x()); + else if (point.x() > maxcorner.x()) + maxcorner.setX(point.x()); + if (point.y() < mincorner.y()) + mincorner.setY(point.y()); + else if (point.y() > maxcorner.y()) + maxcorner.setY(point.y()); + if (point.z() < mincorner.z()) + mincorner.setZ(point.z()); + else if (point.z() > maxcorner.z()) + maxcorner.setZ(point.z()); + } else if (boxtype == Null) { + boxtype = Finite; + mincorner = point; + maxcorner = point; + } +} + +/*! + Unites this box with \a box by expanding this box to encompass the + region defined by \a box. If \a box is already contained within + this box, then this box will be unchanged. + + \sa united(), intersect() +*/ +void Q3DBox::unite(const Q3DBox& box) +{ + if (box.boxtype == Finite) { + unite(box.minimum()); + unite(box.maximum()); + } else if (box.boxtype == Infinite) { + setToInfinite(); + } +} + +/*! + Returns a new box which unites this box with \a point. The returned + value will be the smallest box that contains both this box and \a point. + + \sa unite(), intersected() +*/ +Q3DBox Q3DBox::united(const QVector3D& point) const +{ + if (boxtype == Finite) { + Q3DBox result(*this); + result.unite(point); + return result; + } else if (boxtype == Null) { + return Q3DBox(point, point); + } else { + return *this; + } +} + +/*! + Returns a new box which unites this box with \a box. The returned value + will be the smallest box that contains both this box and \a box. + + \sa unite(), intersected() +*/ +Q3DBox Q3DBox::united(const Q3DBox& box) const +{ + if (boxtype == Finite) { + Q3DBox result(*this); + result.unite(box); + return result; + } else if (boxtype == Null) { + return box; + } else { + return *this; + } +} + +/*! + Transforms this box according to \a matrix. Each of the 8 box + corners are transformed and then a new box that encompasses all + of the transformed corner values is created. + + \sa transformed() +*/ +void Q3DBox::transform(const QMatrix4x4& matrix) +{ + *this = transformed(matrix); +} + +/*! + Returns this box transformed by \a matrix. Each of the 8 box + corners are transformed and then a new box that encompasses all + of the transformed corner values is returned. + + \sa transform() +*/ +Q3DBox Q3DBox::transformed(const QMatrix4x4& matrix) const +{ + if (boxtype != Finite) + return *this; + Q3DBox result; + result.unite(matrix * mincorner); + result.unite(matrix * QVector3D(mincorner.x(), mincorner.y(), maxcorner.z())); + result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), maxcorner.z())); + result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), mincorner.z())); + result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), mincorner.z())); + result.unite(matrix * QVector3D(maxcorner.x(), maxcorner.y(), mincorner.z())); + result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), maxcorner.z())); + result.unite(matrix * maxcorner); + return result; +} + +/*! + \fn bool Q3DBox::operator==(const Q3DBox& box) const + + Returns true if this box is identical to \a box. +*/ + +/*! + \fn bool Q3DBox::operator!=(const Q3DBox& box) const + + Returns true if this box is not identical to \a box. +*/ + +/*! + \fn bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2) + \relates Q3DBox + + Returns true if \a box1 and \a box2 are almost equal; false otherwise. +*/ + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const Q3DBox &box) +{ + if (box.isFinite()) { + dbg.nospace() << "Q3DBox((" + << box.minimum().x() << ", " << box.minimum().y() << ", " + << box.minimum().z() << ") - (" + << box.maximum().x() << ", " << box.maximum().y() << ", " + << box.maximum().z() << "))"; + return dbg.space(); + } else if (box.isNull()) { + dbg << "Q3DBox(null)"; + return dbg; + } else { + dbg << "Q3DBox(infinite)"; + return dbg; + } +} + +#endif + +#ifndef QT_NO_DATASTREAM + +/*! + \relates Q3DBox + + Writes the given \a box to the given \a stream and returns a + reference to the stream. +*/ +QDataStream &operator<<(QDataStream &stream, const Q3DBox &box) +{ + if (box.isNull()) { + stream << int(0); + } else if (box.isInfinite()) { + stream << int(2); + } else { + stream << int(1); + stream << box.minimum(); + stream << box.maximum(); + } + return stream; +} + +/*! + \relates Q3DBox + + Reads a 3D box from the given \a stream into the given \a box + and returns a reference to the stream. +*/ +QDataStream &operator>>(QDataStream &stream, Q3DBox &box) +{ + int type; + stream >> type; + if (type == 1) { + QVector3D minimum, maximum; + stream >> minimum; + stream >> maximum; + box = Q3DBox(minimum, maximum); + } else if (type == 2) { + box.setToInfinite(); + } else { + box.setToNull(); + } + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dbox.h b/src/datavis3d/engine/q3dbox.h new file mode 100644 index 00000000..f41eda36 --- /dev/null +++ b/src/datavis3d/engine/q3dbox.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef Q3DBOX_H +#define Q3DBOX_H + +#include "datavis3dglobal_p.h" + +class QMatrix4x4; + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QT_DATAVIS3D_EXPORT Q3DBox +{ +public: + Q3DBox(); + Q3DBox(const QVector3D& corner1, const QVector3D& corner2); + + bool isNull() const; + bool isFinite() const; + bool isInfinite() const; + + QVector3D minimum() const; + QVector3D maximum() const; + void setExtents(const QVector3D& corner1, const QVector3D& corner2); + + void setToNull(); + void setToInfinite(); + + QVector3D size() const; + QVector3D center() const; + + bool contains(const QVector3D& point) const; + bool contains(const Q3DBox& box) const; + + bool intersects(const Q3DBox& box) const; + void intersect(const Q3DBox& box); + Q3DBox intersected(const Q3DBox& box) const; + + void unite(const QVector3D& point); + void unite(const Q3DBox& box); + + Q3DBox united(const QVector3D& point) const; + Q3DBox united(const Q3DBox& box) const; + + void transform(const QMatrix4x4& matrix); + Q3DBox transformed(const QMatrix4x4& matrix) const; + + bool operator==(const Q3DBox& box) const; + bool operator!=(const Q3DBox& box) const; + + friend bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2); + +private: + enum Type + { + Null, + Finite, + Infinite + }; + + Q3DBox::Type boxtype; + QVector3D mincorner, maxcorner; +}; + +inline Q3DBox::Q3DBox() : boxtype(Null), mincorner(0, 0, 0), maxcorner(0, 0, 0) {} + +inline Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2) + : boxtype(Finite), + mincorner(qMin(corner1.x(), corner2.x()), + qMin(corner1.y(), corner2.y()), + qMin(corner1.z(), corner2.z())), + maxcorner(qMax(corner1.x(), corner2.x()), + qMax(corner1.y(), corner2.y()), + qMax(corner1.z(), corner2.z())) {} + +inline bool Q3DBox::isNull() const { return (boxtype == Null); } +inline bool Q3DBox::isFinite() const { return (boxtype == Finite); } +inline bool Q3DBox::isInfinite() const { return (boxtype == Infinite); } + +inline QVector3D Q3DBox::minimum() const { return mincorner; } +inline QVector3D Q3DBox::maximum() const { return maxcorner; } + +inline void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2) +{ + boxtype = Finite; + mincorner = QVector3D(qMin(corner1.x(), corner2.x()), + qMin(corner1.y(), corner2.y()), + qMin(corner1.z(), corner2.z())); + maxcorner = QVector3D(qMax(corner1.x(), corner2.x()), + qMax(corner1.y(), corner2.y()), + qMax(corner1.z(), corner2.z())); +} + +inline void Q3DBox::setToNull() +{ + boxtype = Null; + mincorner = QVector3D(0, 0, 0); + maxcorner = QVector3D(0, 0, 0); +} + +inline void Q3DBox::setToInfinite() +{ + boxtype = Infinite; + mincorner = QVector3D(0, 0, 0); + maxcorner = QVector3D(0, 0, 0); +} + +inline QVector3D Q3DBox::size() const { return maxcorner - mincorner; } +inline QVector3D Q3DBox::center() const { return (mincorner + maxcorner) * 0.5f; } + +inline bool Q3DBox::contains(const QVector3D& point) const +{ + if (boxtype == Finite) { + return (point.x() >= mincorner.x() && point.x() <= maxcorner.x() && + point.y() >= mincorner.y() && point.y() <= maxcorner.y() && + point.z() >= mincorner.z() && point.z() <= maxcorner.z()); + } else if (boxtype == Infinite) { + return true; + } else { + return false; + } +} + +inline bool Q3DBox::contains(const Q3DBox& box) const +{ + if (box.boxtype == Finite) + return contains(box.mincorner) && contains(box.maxcorner); + else if (box.boxtype == Infinite) + return (boxtype == Infinite); + else + return false; +} + +inline bool Q3DBox::operator==(const Q3DBox& box) const +{ + return (boxtype == box.boxtype && + mincorner == box.mincorner && + maxcorner == box.maxcorner); +} + +inline bool Q3DBox::operator!=(const Q3DBox& box) const +{ + return (boxtype != box.boxtype || + mincorner != box.mincorner || + maxcorner != box.maxcorner); +} + +inline bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2) +{ + return box1.boxtype == box2.boxtype && + qFuzzyCompare(box1.mincorner, box2.mincorner) && + qFuzzyCompare(box1.maxcorner, box2.maxcorner); +} + +#ifndef QT_NO_DEBUG_STREAM +QT_DATAVIS3D_EXPORT QDebug operator<<(QDebug dbg, const Q3DBox &box); +#endif + +#ifndef QT_NO_DATASTREAM +QT_DATAVIS3D_EXPORT QDataStream &operator<<(QDataStream &stream, const Q3DBox &box); +QT_DATAVIS3D_EXPORT QDataStream &operator>>(QDataStream &stream, Q3DBox &box); +#endif + +//Q_DECLARE_METATYPE(Q3DBox) + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/engine/q3dcamera.cpp b/src/datavis3d/engine/q3dcamera.cpp new file mode 100644 index 00000000..480af9b6 --- /dev/null +++ b/src/datavis3d/engine/q3dcamera.cpp @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "q3dcamera.h" +#include "q3dcamera_p.h" +#include "q3dscene.h" +#include "q3dbox.h" +#include "q3dobject.h" + +#include +#include + +QT_DATAVIS3D_BEGIN_NAMESPACE + +Q3DCamera::Q3DCamera(QObject *parent) : + Q3DObject(parent), + d_ptr(new Q3DCameraPrivate(this)) +{ +} + +Q3DCamera::~Q3DCamera() +{ +} + +void Q3DCamera::copyValuesFrom(const Q3DCamera &source) +{ + Q3DObject::copyValuesFrom(source); + + d_ptr->m_target.setX(source.d_ptr->m_target.x()); + d_ptr->m_target.setY(source.d_ptr->m_target.y()); + d_ptr->m_target.setZ(source.d_ptr->m_target.z()); + + d_ptr->m_up.setX(source.d_ptr->m_up.x()); + d_ptr->m_up.setY(source.d_ptr->m_up.y()); + d_ptr->m_up.setZ(source.d_ptr->m_up.z()); + + float *values = new float[16]; + source.d_ptr->m_viewMatrix.copyDataTo(values); + d_ptr->m_viewMatrix = QMatrix4x4(values); + delete values; + + d_ptr->m_xRotation = source.d_ptr->m_xRotation; + d_ptr->m_yRotation = source.d_ptr->m_yRotation; + + d_ptr->m_zoomLevel = source.d_ptr->m_zoomLevel; + d_ptr->m_activePreset = source.d_ptr->m_activePreset; +} + +void Q3DCamera::setRotations(const QPointF &rotation) +{ + setRotationsPrivate(rotation); + d_ptr->m_activePreset = QDataVis::NoPreset; +} + +void Q3DCamera::setDefaultOrientation(const QVector3D &defaultPosition, + const QVector3D &defaultTarget, + const QVector3D &defaultUp) +{ + Q3DObject::setPosition(defaultPosition); + d_ptr->m_target = defaultTarget; + d_ptr->m_up = defaultUp; +} + +QPointF Q3DCamera::rotations() const +{ + QPointF rotations(d_ptr->m_xRotation, d_ptr->m_yRotation); + return rotations; +} + +void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix) +{ + d_ptr->m_viewMatrix = viewMatrix; +} + +QMatrix4x4 Q3DCamera::viewMatrix() const +{ + return d_ptr->m_viewMatrix; +} + +void Q3DCamera::updateViewMatrix(GLfloat zoomAdjustment) +{ + bool showUnder = parentScene()->isUnderSideCameraEnabled(); + int zoom = zoomLevel() * zoomAdjustment; + QMatrix4x4 viewMatrix; + GLfloat lowerLimit = 0.0f; + if (showUnder) + lowerLimit = -90.0f; + + // Reset at 360 in x and limit to 0...90 in y + if (qAbs(d_ptr->m_xRotation) >= 360.0f) + d_ptr->m_xRotation = 0.0f; + if (d_ptr->m_yRotation >= 90.0f) + d_ptr->m_yRotation = 90.0f; + else if (d_ptr->m_yRotation <= lowerLimit) + d_ptr->m_yRotation = lowerLimit; + + // Apply to view matrix + viewMatrix.lookAt(position(), d_ptr->m_target, d_ptr->m_up); + // Compensate for translation (if d_ptr->m_target is off origin) + viewMatrix.translate(d_ptr->m_target.x(), d_ptr->m_target.y(), d_ptr->m_target.z()); + // Apply rotations + // Handle x and z rotation when y -angle is other than 0 + viewMatrix.rotate(d_ptr->m_xRotation, 0, qCos(qDegreesToRadians(d_ptr->m_yRotation)), + qSin(qDegreesToRadians(d_ptr->m_yRotation))); + // y rotation is always "clean" + viewMatrix.rotate(d_ptr->m_yRotation, 1.0f, 0.0f, 0.0f); + // handle zoom by scaling + viewMatrix.scale((GLfloat)zoom / 100.0f); + // Compensate for translation (if d_ptr->m_target is off origin) + viewMatrix.translate(-d_ptr->m_target.x(), -d_ptr->m_target.y(), -d_ptr->m_target.z()); + + setViewMatrix(viewMatrix); +} + +QDataVis::CameraPreset Q3DCamera::cameraPreset() +{ + return d_ptr->m_activePreset; +} + +void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset) +{ + switch (preset) { + case QDataVis::PresetFrontLow: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, 0.0f)); + break; + } + case QDataVis::PresetFront: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, 22.5f)); + break; + } + case QDataVis::PresetFrontHigh: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, 45.0f)); + break; + } + case QDataVis::PresetLeftLow: { + Q3DCamera::setRotationsPrivate(QPointF(90.0f, 0.0f)); + break; + } + case QDataVis::PresetLeft: { + Q3DCamera::setRotationsPrivate(QPointF(90.0f, 22.5f)); + break; + } + case QDataVis::PresetLeftHigh: { + Q3DCamera::setRotationsPrivate(QPointF(90.0f, 45.0f)); + break; + } + case QDataVis::PresetRightLow: { + Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 0.0f)); + break; + } + case QDataVis::PresetRight: { + Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 22.5f)); + break; + } + case QDataVis::PresetRightHigh: { + Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 45.0f)); + break; + } + case QDataVis::PresetBehindLow: { + Q3DCamera::setRotationsPrivate(QPointF(180.0f, 0.0f)); + break; + } + case QDataVis::PresetBehind: { + Q3DCamera::setRotationsPrivate(QPointF(180.0f, 22.5f)); + break; + } + case QDataVis::PresetBehindHigh: { + Q3DCamera::setRotationsPrivate(QPointF(180.0f, 45.0f)); + break; + } + case QDataVis::PresetIsometricLeft: { + Q3DCamera::setRotationsPrivate(QPointF(45.0f, 22.5f)); + break; + } + case QDataVis::PresetIsometricLeftHigh: { + Q3DCamera::setRotationsPrivate(QPointF(45.0f, 45.0f)); + break; + } + case QDataVis::PresetIsometricRight: { + Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 22.5f)); + break; + } + case QDataVis::PresetIsometricRightHigh: { + Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 45.0f)); + break; + } + case QDataVis::PresetDirectlyAbove: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, 90.0f)); + break; + } + case QDataVis::PresetDirectlyAboveCW45: { + Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 90.0f)); + break; + } + case QDataVis::PresetDirectlyAboveCCW45: { + Q3DCamera::setRotationsPrivate(QPointF(45.0f, 90.0f)); + break; + } + case QDataVis::PresetFrontBelow: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, -45.0f)); + break; + } + case QDataVis::PresetLeftBelow: { + Q3DCamera::setRotationsPrivate(QPointF(90.0f, -45.0f)); + break; + } + case QDataVis::PresetRightBelow: { + Q3DCamera::setRotationsPrivate(QPointF(-90.0f, -45.0f)); + break; + } + case QDataVis::PresetBehindBelow: { + Q3DCamera::setRotationsPrivate(QPointF(180.0f, -45.0f)); + break; + } + case QDataVis::PresetDirectlyBelow: { + Q3DCamera::setRotationsPrivate(QPointF(0.0f, -90.0f)); + break; + } + default: + preset = QDataVis::NoPreset; + break; + } + + d_ptr->m_activePreset = preset; +} + +void Q3DCamera::setRotationsPrivate(const QPointF &rotation) +{ + d_ptr->m_xRotation = rotation.x(); + d_ptr->m_yRotation = rotation.y(); +} + +void Q3DCamera::setZoomLevel(int zoomLevel) +{ + d_ptr->m_zoomLevel = zoomLevel; +} + +int Q3DCamera::zoomLevel() +{ + return d_ptr->m_zoomLevel; +} + +QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relativePosition, + GLfloat fixedRotation, + GLfloat distanceModifier) const +{ + // Move the position with camera + GLfloat radiusFactor = relativePosition.z() * (1.5f + distanceModifier); + GLfloat xAngle; + GLfloat yAngle; + if (!fixedRotation) { + xAngle = qDegreesToRadians(d_ptr->m_xRotation); + yAngle = qDegreesToRadians(d_ptr->m_yRotation); + } else { + xAngle = qDegreesToRadians(fixedRotation); + yAngle = 0; + } + GLfloat radius = (radiusFactor + relativePosition.y()); // set radius to match the highest height of the position + GLfloat zPos = radius * qCos(xAngle) * qCos(yAngle); + GLfloat xPos = radius * qSin(xAngle) * qCos(yAngle); + GLfloat yPos = (radiusFactor + relativePosition.y()) * qSin(yAngle); + // Keep in the set position in relation to camera + return QVector3D(-xPos + relativePosition.x(), + yPos + relativePosition.y(), + zPos + relativePosition.z()); +} + + +Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) : + q_ptr(q), + m_zoomLevel(100) +{ +} + + +Q3DCameraPrivate::~Q3DCameraPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dcamera.h b/src/datavis3d/engine/q3dcamera.h new file mode 100644 index 00000000..35eaaea7 --- /dev/null +++ b/src/datavis3d/engine/q3dcamera.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef Q3DCAMERA_H +#define Q3DCAMERA_H + +#include +#include + +#include "datavis3dglobal_p.h" +#include "q3dbars.h" +#include "q3dobject.h" + +class QVector3D; +class QPoint; +class QPointF; + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DCameraPrivate; + +class QT_DATAVIS3D_EXPORT Q3DCamera : public Q3DObject +{ + Q_OBJECT + Q_PROPERTY(QPointF rotations READ rotations WRITE setRotations) + Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix) + Q_PROPERTY(QtDataVis3D::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset) + Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel) + + +public: + Q3DCamera(QObject *parent = 0); + virtual ~Q3DCamera(); + + void copyValuesFrom(const Q3DCamera &source); + + // Set camera rotation in degrees + virtual void setRotations(const QPointF &rotation); + // Get camera rotations + virtual QPointF rotations() const; + + virtual void setViewMatrix(const QMatrix4x4 &viewMatrix); + virtual QMatrix4x4 viewMatrix() const; + + // Set default camera orientation. Position's x and y should be 0. + virtual void setDefaultOrientation(const QVector3D &defaultPosition, + const QVector3D &defaultTarget, + const QVector3D &defaultUp); + + // Calculate view matrix based on zoomadjustment, current rotation and current zoom level + virtual void updateViewMatrix(GLfloat zoomAdjustment); + + virtual void setCameraPreset(QDataVis::CameraPreset preset); + virtual QDataVis::CameraPreset cameraPreset(); + + virtual void setZoomLevel(int zoomLevel); + virtual int zoomLevel(); + + virtual QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition, + GLfloat fixedRotation, + GLfloat distanceModifier) const; + +private: + void setRotationsPrivate(const QPointF &rotation); + QScopedPointer d_ptr; + + Q_DISABLE_COPY(Q3DCamera) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DCAMERA_H diff --git a/src/datavis3d/engine/q3dcamera_p.h b/src/datavis3d/engine/q3dcamera_p.h new file mode 100644 index 00000000..b8b1e913 --- /dev/null +++ b/src/datavis3d/engine/q3dcamera_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Q3DCAMERA_P_H +#define Q3DCAMERA_P_H + +#include "datavis3dglobal_p.h" +#include "q3dbars.h" +#include + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DCamera; + +class Q3DCameraPrivate +{ +public: + Q3DCameraPrivate(Q3DCamera *q); + ~Q3DCameraPrivate(); + +public: + Q3DCamera *q_ptr; + QVector3D m_target; + QVector3D m_up; + + QMatrix4x4 m_viewMatrix; + + GLfloat m_xRotation; + GLfloat m_yRotation; + int m_zoomLevel; + QDataVis::CameraPreset m_activePreset; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DCAMERA_P_H diff --git a/src/datavis3d/engine/q3dlight.cpp b/src/datavis3d/engine/q3dlight.cpp new file mode 100644 index 00000000..44fe11c6 --- /dev/null +++ b/src/datavis3d/engine/q3dlight.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "q3dlight.h" +#include "q3dscene.h" +#include "q3dlight_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +Q3DLight::Q3DLight(QObject *parent) : + Q3DObject(parent), + d_ptr(new Q3DLightPrivate(this)) +{ +} + +void Q3DLight::copyValuesFrom(const Q3DLight &source) +{ + Q3DObject::copyValuesFrom(source); +} + +Q3DLight::~Q3DLight() +{ +} + +Q3DLightPrivate::Q3DLightPrivate(Q3DLight *q) : + q_ptr(q) +{ +} + +Q3DLightPrivate::~Q3DLightPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dlight.h b/src/datavis3d/engine/q3dlight.h new file mode 100644 index 00000000..6bbfcadd --- /dev/null +++ b/src/datavis3d/engine/q3dlight.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef Q3DLIGHT_H +#define Q3DLIGHT_H + +#include + +#include "datavis3dglobal_p.h" +#include "q3dobject.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DLightPrivate; +class Q3DScene; + +class QT_DATAVIS3D_EXPORT Q3DLight : public Q3DObject +{ + Q_OBJECT + +public: + Q3DLight(QObject *parent = 0); + virtual ~Q3DLight(); + + void copyValuesFrom(const Q3DLight &source); + +private: + QScopedPointer d_ptr; + + Q_DISABLE_COPY(Q3DLight) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DLIGHT_H diff --git a/src/datavis3d/engine/q3dlight_p.h b/src/datavis3d/engine/q3dlight_p.h new file mode 100644 index 00000000..8bd0dea3 --- /dev/null +++ b/src/datavis3d/engine/q3dlight_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Q3DLIGHT_P_H +#define Q3DLIGHT_P_H + +#include "datavis3dglobal_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DScene; +class Q3DLight; + +class Q3DLightPrivate +{ +public: + Q3DLightPrivate(Q3DLight *q); + ~Q3DLightPrivate(); + +public: + Q3DLight *q_ptr; + +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DLIGHT_P_H + + + + + diff --git a/src/datavis3d/engine/q3dobject.cpp b/src/datavis3d/engine/q3dobject.cpp new file mode 100644 index 00000000..54235ce1 --- /dev/null +++ b/src/datavis3d/engine/q3dobject.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "q3dobject.h" +#include "q3dobject_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +Q3DObject::Q3DObject(QObject *parent) : + QObject(parent), + d_ptr(new Q3DObjectPrivate(this)) +{ +} + +Q3DObject::~Q3DObject() +{ +} + +void Q3DObject::copyValuesFrom(const Q3DObject &source) +{ + d_ptr->m_position.setX(source.d_ptr->m_position.x()); + d_ptr->m_position.setY(source.d_ptr->m_position.y()); + d_ptr->m_position.setZ(source.d_ptr->m_position.z()); +} + +void Q3DObject::setParentScene(Q3DScene *parentScene) +{ + d_ptr->m_parentScene = parentScene; +} + +Q3DScene *Q3DObject::parentScene() +{ + return d_ptr->m_parentScene; +} + +void Q3DObject::setPosition(const QVector3D &position) +{ + d_ptr->m_position = position; +} + +QVector3D Q3DObject::position() const +{ + return d_ptr->m_position; +} + + +Q3DObjectPrivate::Q3DObjectPrivate(Q3DObject *q) : + q_ptr(q), + m_parentScene(0) +{ +} + +Q3DObjectPrivate::~Q3DObjectPrivate() +{ + +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dobject.h b/src/datavis3d/engine/q3dobject.h new file mode 100644 index 00000000..29f759ac --- /dev/null +++ b/src/datavis3d/engine/q3dobject.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef Q3DOBJECT_H +#define Q3DOBJECT_H + +#include +#include "datavis3dglobal_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DScene; +class Q3DObjectPrivate; + +class Q3DObject : public QObject +{ + Q_OBJECT + +public: + Q3DObject(QObject *parent = 0); + virtual ~Q3DObject(); + + void copyValuesFrom(const Q3DObject &source); + + virtual void setParentScene(Q3DScene *parentScene); + virtual Q3DScene *parentScene(); + + virtual void setPosition(const QVector3D &position); + virtual QVector3D position() const; + +private: + QScopedPointer d_ptr; + + Q_DISABLE_COPY(Q3DObject) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DOBJECT_H diff --git a/src/datavis3d/engine/q3dobject_p.h b/src/datavis3d/engine/q3dobject_p.h new file mode 100644 index 00000000..f55be225 --- /dev/null +++ b/src/datavis3d/engine/q3dobject_p.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Q3DOBJECT_P_H +#define Q3DOBJECT_P_H + +#include "datavis3dglobal_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DObject; +class Q3DScene; + +class Q3DObjectPrivate +{ +public: + Q3DObjectPrivate(Q3DObject *q); + ~Q3DObjectPrivate(); + +public: + Q3DObject *q_ptr; + Q3DScene *m_parentScene; + QVector3D m_position; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DOBJECT_P_H diff --git a/src/datavis3d/engine/q3dscene.cpp b/src/datavis3d/engine/q3dscene.cpp new file mode 100644 index 00000000..e0267e7d --- /dev/null +++ b/src/datavis3d/engine/q3dscene.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include + +#include "datavis3dglobal_p.h" + +#include "q3dscene.h" +#include "q3dscene_p.h" +#include "q3dcamera.h" +#include "q3dlight.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +Q3DScene::Q3DScene(QObject *parent) : + d_ptr(new Q3DScenePrivate(this)) +{ +} + +Q3DScene *Q3DScene::clone(QObject *parent) +{ + Q3DScene *cloneScene = new Q3DScene(parent); + cloneScene->setViewport(viewport()); + cloneScene->setMainViewport(mainViewport()); + cloneScene->setSliceViewport(sliceViewport()); + + if (d_ptr->m_camera) { + Q3DCamera *cloneCamera = new Q3DCamera(); + cloneCamera->copyValuesFrom(*d_ptr->m_camera); + cloneScene->setCamera(cloneCamera); + } + + if (d_ptr->m_light) { + Q3DLight *cloneLight = new Q3DLight(); + cloneLight->copyValuesFrom(*d_ptr->m_light); + cloneScene->setLight(cloneLight); + } + + cloneScene->setSlicingActivated(isSlicingActivated()); + cloneScene->setUnderSideCameraEnabled(isUnderSideCameraEnabled()); + + return cloneScene; +} + +Q3DScene::~Q3DScene() +{ +} + +QRect Q3DScene::viewport() const +{ + return d_ptr->m_viewport; +} + +void Q3DScene::setViewport(const QRect &viewport) +{ + d_ptr->m_viewport = viewport; + d_ptr->m_viewport.setX(0); + d_ptr->m_viewport.setY(0); +} + +void Q3DScene::setViewportSize(int width, int height) +{ + d_ptr->m_viewport.setWidth(width); + d_ptr->m_viewport.setHeight(height); +} + +QRect Q3DScene::mainViewport() const +{ + return d_ptr->m_mainViewport; +} + +void Q3DScene::setMainViewport(const QRect &mainViewPort) +{ + d_ptr->m_mainViewport = mainViewPort; +} + +bool Q3DScene::isInputInsideMainView(const QPoint &point) +{ + int x = point.x(); + int y = point.y(); + int areaMinX = d_ptr->m_mainViewport.x(); + int areaMaxX = d_ptr->m_mainViewport.x() + d_ptr->m_mainViewport.width(); + int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_mainViewport.y(); + int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_mainViewport.y() + d_ptr->m_mainViewport.height()); + + return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY ); +} + +bool Q3DScene::isInputInsideSliceView(const QPoint &point) +{ + int x = point.x(); + int y = point.y(); + int areaMinX = d_ptr->m_sliceViewport.x(); + int areaMaxX = d_ptr->m_sliceViewport.x() + d_ptr->m_sliceViewport.width(); + int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_sliceViewport.y(); + int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_sliceViewport.y() + d_ptr->m_sliceViewport.height()); + + return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY ); +} + +QRect Q3DScene::sliceViewport() const +{ + return d_ptr->m_sliceViewport; +} + +void Q3DScene::setSliceViewport(const QRect &sliceViewPort) +{ + d_ptr->m_sliceViewport = sliceViewPort; +} + +// TODO: Refactor the current way of building the scene... +// The scene should have clear ownership of camera, light and other future building blocks of the scene. + +Q3DCamera *Q3DScene::camera() const +{ + return d_ptr->m_camera; +} + +void Q3DScene::setCamera(Q3DCamera *camera) +{ + if (d_ptr->m_camera) + d_ptr->m_camera->setParentScene(0); + + d_ptr->m_camera = camera; + d_ptr->m_camera->setParentScene(this); +} + +Q3DLight *Q3DScene::light() const +{ + return d_ptr->m_light; +} + +void Q3DScene::setLight(Q3DLight *light) +{ + if (d_ptr->m_light) + d_ptr->m_light->setParentScene(0); + + d_ptr->m_light = light; + d_ptr->m_light->setParentScene(this); +} + +bool Q3DScene::isUnderSideCameraEnabled() const +{ + return d_ptr->m_isUnderSideCameraEnabled; +} + +void Q3DScene::setUnderSideCameraEnabled(bool isEnabled) +{ + d_ptr->m_isUnderSideCameraEnabled = isEnabled; +} + +bool Q3DScene::isSlicingActivated() const +{ + return d_ptr->m_isSlicingActivated; +} + +void Q3DScene::setSlicingActivated(bool isSlicing) +{ + if (isSlicing != d_ptr->m_isSlicingActivated) + d_ptr->m_isSlicingActivated = isSlicing; +} + +void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition, GLfloat fixedRotation, GLfloat distanceModifier) +{ + d_ptr->m_light->setPosition(d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition, fixedRotation, distanceModifier)); +} + + +Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) : + q_ptr(q), + m_camera(0), + m_light(0), + m_isUnderSideCameraEnabled(false), + m_isSlicingActivated(false) +{ +} + +Q3DScenePrivate::~Q3DScenePrivate() +{ + delete m_camera; + delete m_light; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/q3dscene.h b/src/datavis3d/engine/q3dscene.h new file mode 100644 index 00000000..bd53e06a --- /dev/null +++ b/src/datavis3d/engine/q3dscene.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef Q3DSCENE_H +#define Q3DSCENE_H + +#include + +#include "datavis3dglobal_p.h" +#include "q3dscene_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DCamera; +class Q3DBox; +class Q3DLight; + +// Note: Scene doesn't take ownership of any of the objects given as parameter. Upon destruction of the scene it will call setParentScene(0) on it's child objects. + +class QT_DATAVIS3D_EXPORT Q3DScene : public QObject +{ + Q_OBJECT + +public: + Q3DScene(QObject *parent = 0); + ~Q3DScene(); + + Q3DScene *clone(QObject *parent = 0); + + QRect viewport() const; + void setViewport(const QRect &viewport); + void setViewportSize(int width, int height); + + QRect mainViewport() const; + void setMainViewport(const QRect &mainViewport); + bool isInputInsideMainView(const QPoint &point); + + QRect sliceViewport() const; + void setSliceViewport(const QRect &sliceViewport); + bool isInputInsideSliceView(const QPoint &point); + + Q3DCamera *camera() const; + void setCamera(Q3DCamera *camera); + + Q3DLight *light() const; + void setLight(Q3DLight *light); + + bool isUnderSideCameraEnabled() const; + void setUnderSideCameraEnabled(bool isEnabled); + + void setSlicingActivated(bool isSlicing); + bool isSlicingActivated() const; + + // Calcluate light position based on rotation. + // Call after calling calculateViewMatrix to get up-to-date position + void setLightPositionRelativeToCamera(const QVector3D &relativePosition, + GLfloat fixedRotation = 0.0f, + GLfloat distanceModifier = 0.0f); + +private: + QScopedPointer d_ptr; + + Q_DISABLE_COPY(Q3DScene) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DSCENE_H diff --git a/src/datavis3d/engine/q3dscene_p.h b/src/datavis3d/engine/q3dscene_p.h new file mode 100644 index 00000000..35ee89be --- /dev/null +++ b/src/datavis3d/engine/q3dscene_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Q3DSCENE_P_H +#define Q3DSCENE_P_H + +#include + +#include "datavis3dglobal_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DCamera; +class Q3DLight; +class Q3DScene; + +class Q3DScenePrivate +{ +public: + Q3DScenePrivate(Q3DScene *q); + ~Q3DScenePrivate(); + + Q3DScene *q_ptr; + QRect m_viewport; + QRect m_mainViewport; + QRect m_sliceViewport; + Q3DCamera *m_camera; + Q3DLight *m_light; + bool m_isUnderSideCameraEnabled; + bool m_isSlicingActivated; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DSCENE_P_H diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp index 67c10f2b..5230e0ff 100644 --- a/src/datavis3d/engine/scatter3dcontroller.cpp +++ b/src/datavis3d/engine/scatter3dcontroller.cpp @@ -31,9 +31,6 @@ QT_DATAVIS3D_BEGIN_NAMESPACE Scatter3DController::Scatter3DController(QRect boundRect) : Abstract3DController(boundRect), - m_mouseState(MouseNone), - m_mousePos(QPoint(0, 0)), - m_isSlicingActivated(false), m_renderer(0), m_selectedItemIndex(noSelectionIndex()) { @@ -93,152 +90,6 @@ void Scatter3DController::synchDataToRenderer() } } -QMatrix4x4 Scatter3DController::calculateViewMatrix(int zoom, int viewPortWidth, - int viewPortHeight, bool showUnder) -{ - return m_cameraHelper->calculateViewMatrix(m_mousePos, - zoom, - viewPortWidth, - viewPortHeight, - showUnder); -} - -bool Scatter3DController::isSlicingActive() -{ - return m_isSlicingActivated; -} - -void Scatter3DController::setSlicingActive(bool isSlicing) -{ - m_isSlicingActivated = isSlicing; - - m_changeTracker.slicingActiveChanged = true; - emitNeedRender(); -} - -Scatter3DController::MouseState Scatter3DController::mouseState() -{ - return m_mouseState; -} - -#if defined(Q_OS_ANDROID) -void Scatter3DController::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (!m_isSlicingActivated) { - m_mouseState = Scatter3DController::MouseOnScene; - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = event->pos(); - emitNeedRender(); - } -} - -void Scatter3DController::touchEvent(QTouchEvent *event) -{ - static int prevDistance = 0; - - QList points; - points = event->touchPoints(); - - if (points.count() == 2) { - m_mouseState = Scatter3DController::MouseOnPinch; - - QPointF distance = points.at(0).pos() - points.at(1).pos(); - int newDistance = distance.manhattanLength(); - int zoomRate = 1; - int zoomLevel = m_zoomLevel; - if (zoomLevel > 100) - zoomRate = 5; - if (newDistance > prevDistance) - zoomLevel += zoomRate; - else - zoomLevel -= zoomRate; - if (zoomLevel > 500) - zoomLevel = 500; - else if (zoomLevel < 10) - zoomLevel = 10; - setZoomLevel(zoomLevel); - prevDistance = newDistance; - //qDebug() << "distance" << distance.manhattanLength(); - } -} -#endif - -void Scatter3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) -{ - QRect mainViewPort = m_renderer->mainViewPort(); - if (Qt::LeftButton == event->button()) { - if (m_isSlicingActivated) { - if (mousePos.x() <= mainViewPort.width() - && mousePos.y() <= mainViewPort.height()) { - m_mouseState = Scatter3DController::MouseOnOverview; - //qDebug() << "Mouse pressed on overview"; - } else { - m_mouseState = Scatter3DController::MouseOnZoom; - //qDebug() << "Mouse pressed on zoom"; - } - } else { -#if !defined(Q_OS_ANDROID) - m_mouseState = Scatter3DController::MouseOnScene; -#else - m_mouseState = Scatter3DController::MouseRotating; -#endif - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - //qDebug() << "Mouse pressed on scene"; - } - } else if (Qt::MiddleButton == event->button()) { - // reset rotations - m_mousePos = QPoint(0, 0); - } else if (Qt::RightButton == event->button()) { -#if !defined(Q_OS_ANDROID) - m_mouseState = Scatter3DController::MouseRotating; -#else - m_mouseState = Scatter3DController::MouseOnScene; -#endif - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - } - m_cameraHelper->updateMousePos(m_mousePos); - emitNeedRender(); -} - -void Scatter3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event); - if (Scatter3DController::MouseRotating == m_mouseState) { - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; - m_cameraHelper->updateMousePos(mousePos); - emitNeedRender(); - } - m_mouseState = Scatter3DController::MouseNone; -} - -void Scatter3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event); - if (Scatter3DController::MouseRotating == m_mouseState) { - m_mousePos = mousePos; - emitNeedRender(); - } -} - -void Scatter3DController::wheelEvent(QWheelEvent *event) -{ - int zoomLevel = m_zoomLevel; - if (zoomLevel > 100) - zoomLevel += event->angleDelta().y() / 12; - else if (zoomLevel > 50) - zoomLevel += event->angleDelta().y() / 60; - else - zoomLevel += event->angleDelta().y() / 120; - if (zoomLevel > 500) - zoomLevel = 500; - else if (zoomLevel < 10) - zoomLevel = 10; - - setZoomLevel(zoomLevel); -} void Scatter3DController::setActiveDataProxy(QAbstractDataProxy *proxy) { @@ -385,11 +236,6 @@ int Scatter3DController::selectedItemIndex() const return m_selectedItemIndex; } -QPoint Scatter3DController::mousePosition() -{ - return m_mousePos; -} - void Scatter3DController::adjustValueAxisRange() { if (m_data) { diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavis3d/engine/scatter3dcontroller_p.h index fd7d82ad..fb1b693f 100644 --- a/src/datavis3d/engine/scatter3dcontroller_p.h +++ b/src/datavis3d/engine/scatter3dcontroller_p.h @@ -57,11 +57,6 @@ class QT_DATAVIS3D_EXPORT Scatter3DController : public Abstract3DController private: Scatter3DChangeBitField m_changeTracker; - // Interaction - MouseState m_mouseState; - QPoint m_mousePos; - bool m_isSlicingActivated; - // Rendering Scatter3DRenderer *m_renderer; int m_selectedItemIndex; @@ -72,15 +67,6 @@ public: void initializeOpenGL(); - MouseState mouseState(); - QPoint mousePosition(); - - bool isSlicingActive(); - void setSlicingActive(bool isSlicing); - - QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, - bool showUnder = false); - // Object type void setObjectType(QDataVis::MeshStyle style, bool smooth = false); @@ -91,15 +77,6 @@ public: int selectedItemIndex() const; static inline int noSelectionIndex() { return -1; } -#if defined(Q_OS_ANDROID) - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); -#endif - void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); - void wheelEvent(QWheelEvent *event); - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); void synchDataToRenderer(); diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp index 151d1d2f..43baaf4e 100644 --- a/src/datavis3d/engine/scatter3drenderer.cpp +++ b/src/datavis3d/engine/scatter3drenderer.cpp @@ -18,11 +18,12 @@ #include "scatter3drenderer_p.h" #include "scatter3dcontroller_p.h" -#include "camerahelper_p.h" +#include "q3dcamera.h" #include "shaderhelper_p.h" #include "objecthelper_p.h" #include "texturehelper_p.h" #include "utils_p.h" +#include "q3dlight.h" #include #include @@ -160,25 +161,37 @@ void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy) Abstract3DRenderer::updateDataModel(dataProxy); } -void Scatter3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) +void Scatter3DRenderer::updateScene(Q3DScene *scene) { - // Handle GL state setup for FBO buffers and clearing of the render surface - Abstract3DRenderer::render(camera, defaultFboHandle); + // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. + scene->setMainViewport(m_mainViewPort); + scene->setUnderSideCameraEnabled(true); if (m_hasHeightAdjustmentChanged) { - // Set initial camera position. Also update if height adjustment has changed. - camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), - QVector3D(0.0f, 0.0f, zComp), - QVector3D(0.0f, 1.0f, 0.0f)); + // Set initial m_cachedScene->camera() position. Also update if height adjustment has changed. + scene->camera()->setDefaultOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), + QVector3D(0.0f, 0.0f, zComp), + QVector3D(0.0f, 1.0f, 0.0f)); m_hasHeightAdjustmentChanged = false; } + scene->camera()->updateViewMatrix(m_autoScaleAdjustment); + // Set light position (rotate light with m_cachedScene->camera(), a bit above it (as set in defaultLightPos)) + scene->setLightPositionRelativeToCamera(defaultLightPos); + + Abstract3DRenderer::updateScene(scene); +} + +void Scatter3DRenderer::render(GLuint defaultFboHandle) +{ + // Handle GL state setup for FBO buffers and clearing of the render surface + Abstract3DRenderer::render(defaultFboHandle); + // Draw dots scene - drawScene(camera, defaultFboHandle); + drawScene(defaultFboHandle); } -void Scatter3DRenderer::drawScene(CameraHelper *camera, - const GLuint defaultFboHandle) +void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) { GLfloat backgroundRotation = 0; @@ -192,11 +205,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f); // Calculate view matrix - QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - m_cachedZoomLevel * m_autoScaleAdjustment, - m_mainViewPort.width(), - m_mainViewPort.height(), - true); + QMatrix4x4 viewMatrix = m_cachedScene->camera()->viewMatrix(); // Calculate label flipping if (viewMatrix.row(0).x() > 0) @@ -224,8 +233,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, else if (m_zFlipped && !m_xFlipped) backgroundRotation = 0.0f; - // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos)) - QVector3D lightPos = camera->calculateLightPosition(defaultLightPos); + // Get light position from the scene + QVector3D lightPos = m_cachedScene->light()->position(); // Map adjustment direction to model matrix scaling // TODO: Let's use these for testing the autoscaling of dots based on their number @@ -260,12 +269,13 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Get the depth view matrix // It may be possible to hack lightPos here if we want to make some tweaks to shadow - QVector3D depthLightPos = camera->calculateLightPosition( + QVector3D depthLightPos = m_cachedScene->camera()->calculatePositionRelativeToCamera( defaultLightPos, 0.0f, 1.0f / m_autoScaleAdjustment); depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, 0.0f, zComp), QVector3D(0.0f, 1.0f, 0.0f)); - // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed - //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); + // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? + // That causes the scene to be not drawn from above -> must be fixed + // qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); // Set the depth projection matrix #ifndef USE_WIDER_SHADOWS // Use this for perspective shadows @@ -413,9 +423,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, glEnable(GL_DITHER); // Read color under cursor - if (Scatter3DController::MouseOnScene == m_controller->mouseState()) - m_selection = Utils::getSelection(m_controller->mousePosition(), + if (QDataVis::InputOnScene == m_controller->inputState()) { + m_selection = Utils::getSelection(m_controller->inputPosition(), m_cachedBoundingRect.height()); + } glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -701,7 +712,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -710,7 +721,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -719,7 +730,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, { // Set shadowless shader bindings lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength); + m_cachedTheme.m_lightStrength); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj); @@ -755,7 +766,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -764,7 +775,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -773,7 +784,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, { // Set shadowless shader bindings lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength); + m_cachedTheme.m_lightStrength); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj); @@ -831,7 +842,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -840,7 +851,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -884,7 +895,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -893,7 +904,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -902,7 +913,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, { // Set shadowless shader bindings lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength); + m_cachedTheme.m_lightStrength); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj); @@ -956,7 +967,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -965,7 +976,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -1023,7 +1034,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, // Set the rest of the shader bindings lineShader->setUniformValue(lineShader->model(), modelMatrix); lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); + itModelMatrix.inverted().transposed()); lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) @@ -1032,7 +1043,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength / 10.0f); + m_cachedTheme.m_lightStrength / 10.0f); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); @@ -1041,7 +1052,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, { // Set shadowless shader bindings lineShader->setUniformValue(lineShader->lightS(), - m_cachedTheme.m_lightStrength); + m_cachedTheme.m_lightStrength); // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj); @@ -1120,7 +1131,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, 0.0f, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } labelNbr++; @@ -1180,7 +1191,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, 0.0f, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } labelNbr++; @@ -1233,7 +1244,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, 0.0f, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); // Side wall @@ -1255,7 +1266,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, 0.0f, zComp), QVector3D(rotLabelX, rotLabelY, rotLabelZ), 0, m_cachedSelectionMode, - m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid, + m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid, alignment); } labelNbr++; @@ -1323,7 +1334,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, QVector3D(0.0f, 0.0f, zComp), QVector3D(0.0f, 0.0f, 0.0f), 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, camera, true, false, Drawer::LabelMid); + m_labelObj, m_cachedScene->camera(), true, false, Drawer::LabelMid); // Reset label update flag; they should have been updated when we get here m_updateLabels = false; diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavis3d/engine/scatter3drenderer_p.h index 18752d59..c8f5b765 100644 --- a/src/datavis3d/engine/scatter3drenderer_p.h +++ b/src/datavis3d/engine/scatter3drenderer_p.h @@ -44,8 +44,8 @@ QT_DATAVIS3D_BEGIN_NAMESPACE class ShaderHelper; class ObjectHelper; class LabelItem; -class CameraHelper; -class Q3DAbstractAxisPrivate; +class Q3DScene; +class QAbstractAxisPrivate; class QT_DATAVIS3D_EXPORT Scatter3DRenderer : public Abstract3DRenderer { @@ -99,7 +99,8 @@ public: ~Scatter3DRenderer(); void updateDataModel(QScatterDataProxy *dataProxy); - void render(CameraHelper *camera, const GLuint defaultFboHandle); + void updateScene(Q3DScene *scene); + void render(GLuint defaultFboHandle); QRect mainViewPort(); @@ -112,7 +113,7 @@ private: virtual void updateShadowQuality(QDataVis::ShadowQuality quality); virtual void updateTextures(); - void drawScene(CameraHelper *camera, const GLuint defaultFboHandle); + void drawScene(GLuint defaultFboHandle); void handleResize(); void loadBackgroundMesh(); diff --git a/src/datavis3d/engine/selectionpointer.cpp b/src/datavis3d/engine/selectionpointer.cpp index c1b28f62..8746c8d1 100644 --- a/src/datavis3d/engine/selectionpointer.cpp +++ b/src/datavis3d/engine/selectionpointer.cpp @@ -21,9 +21,10 @@ #include "shaderhelper_p.h" #include "objecthelper_p.h" #include "texturehelper_p.h" -#include "camerahelper_p.h" +#include "q3dcamera.h" #include "drawer_p.h" #include "utils_p.h" +#include "q3dlight.h" #include #include @@ -41,6 +42,7 @@ SelectionPointer::SelectionPointer(Surface3DController *controller) m_pointObj(0), m_textureHelper(0), m_isInitialized(false), + m_cachedScene(0), m_font(QFont(QStringLiteral("Arial"))), m_labelTransparency(QDataVis::TransparencyFromTheme), m_drawer(new Drawer(m_cachedTheme, m_font, m_labelTransparency)) @@ -56,6 +58,7 @@ SelectionPointer::~SelectionPointer() delete m_pointObj; delete m_textureHelper; delete m_drawer; + delete m_cachedScene; } void SelectionPointer::initializeOpenGL() @@ -79,20 +82,26 @@ void SelectionPointer::initializeOpenGL() m_isInitialized = true; } -void SelectionPointer::render(CameraHelper *camera, const GLuint defaultFboHandle) +void SelectionPointer::updateScene(Q3DScene *scene) +{ + // Make a copy of the scene. + delete m_cachedScene; + m_cachedScene = scene->clone(); +} + +void SelectionPointer::render(GLuint defaultFboHandle) { Q_UNUSED(defaultFboHandle) + Q3DCamera *camera = m_cachedScene->camera(); QSize textureSize = m_labelItem.size(); QMatrix4x4 itModelMatrix; // Calculate view matrix - QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - 100.0f, //TODO: m_zoomLevel * m_autoScaleAdjustment - m_mainViewPort.width(), - m_mainViewPort.height(), - false/*m_hasNegativeValues*/); + //TODO: m_autoScaleAdjustment + camera->updateViewMatrix(1.0f); + QMatrix4x4 viewMatrix = camera->viewMatrix(); itModelMatrix.scale(m_scale); @@ -119,7 +128,7 @@ void SelectionPointer::render(CameraHelper *camera, const GLuint defaultFboHandl // Enable texturing glEnable(GL_TEXTURE_2D); - QVector3D lightPos = camera->calculateLightPosition(defaultLightPos); + QVector3D lightPos = m_cachedScene->light()->position(); // // Draw the point @@ -149,7 +158,7 @@ void SelectionPointer::render(CameraHelper *camera, const GLuint defaultFboHandl modelMatrixLabel.translate(m_position * m_scale + labelAlign + QVector3D(0.0f, 0.0f, zComp)); // Position the label towards the camera - QPointF camRotations = camera->getCameraRotations(); + QPointF camRotations = camera->rotations(); modelMatrixLabel.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f); modelMatrixLabel.rotate(-camRotations.y(), 1.0f, 0.0f, 0.0f); diff --git a/src/datavis3d/engine/selectionpointer_p.h b/src/datavis3d/engine/selectionpointer_p.h index 19cada6f..13ff42e3 100644 --- a/src/datavis3d/engine/selectionpointer_p.h +++ b/src/datavis3d/engine/selectionpointer_p.h @@ -35,6 +35,7 @@ #include #include +#include "q3dscene.h" #include "datavis3dglobal_p.h" #include "surface3dcontroller_p.h" @@ -48,7 +49,7 @@ class SurfaceObject; class TextureHelper; class Theme; class Drawer; -class CameraHelper; +class Q3DCamera; class QT_DATAVIS3D_EXPORT SelectionPointer : public QObject, protected QOpenGLFunctions { @@ -59,12 +60,13 @@ public: ~SelectionPointer(); void initializeOpenGL(); - void render(CameraHelper *camera, const GLuint defaultFboHandle = 0); + void render(GLuint defaultFboHandle = 0); void setPosition(QVector3D position); void setScaling(QVector3D scaling); void setLabel(QString label); void updateTheme(Theme theme); void updateBoundingRect(QRect rect); + void updateScene(Q3DScene *scene); private: void initShaders(); @@ -87,6 +89,7 @@ private: QRect m_mainViewPort; QVector3D m_position; QVector3D m_scale; + Q3DScene *m_cachedScene; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/surface3dcontroller.cpp b/src/datavis3d/engine/surface3dcontroller.cpp index 01e24a92..8b7d38a7 100644 --- a/src/datavis3d/engine/surface3dcontroller.cpp +++ b/src/datavis3d/engine/surface3dcontroller.cpp @@ -35,9 +35,7 @@ Surface3DController::Surface3DController(QRect rect) : Abstract3DController(rect), m_renderer(0), m_smoothSurface(false), - m_surfaceGrid(true), - m_mouseState(MouseNone), - m_mousePos(QPoint(0, 0)) + m_surfaceGrid(true) { setActiveDataProxy(0); @@ -47,6 +45,8 @@ Surface3DController::Surface3DController(QRect rect) setAxisX(0); setAxisY(0); setAxisZ(0); + QObject::connect(m_activeInputHandler, &QAbstract3DInputHandler::selectionAtPoint, + this, &Surface3DController::handleSelectionAtPoint); } Surface3DController::~Surface3DController() @@ -87,15 +87,6 @@ void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstr // TODO: Implement! } -QMatrix4x4 Surface3DController::calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder) -{ - return m_cameraHelper->calculateViewMatrix(m_mousePos, - zoom, - viewPortWidth, - viewPortHeight, - showUnder); -} - void Surface3DController::setSmoothSurface(bool enable) { m_smoothSurface = enable; @@ -120,67 +111,6 @@ bool Surface3DController::surfaceGrid() return m_surfaceGrid; } - -#if defined(Q_OS_ANDROID) -void Surface3DController::mouseDoubleClickEvent(QMouseEvent *event) -{ - Q_UNUSED(event) -} -void touchEvent(QTouchEvent *event) -{ - Q_UNUSED(event) -} -#endif - -void Surface3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) -{ - if (Qt::LeftButton == event->button()) { - m_mousePos = mousePos; - emit leftMousePressed(mousePos); - } else if (Qt::RightButton == event->button()) { - #if !defined(Q_OS_ANDROID) - m_mouseState = Abstract3DController::MouseRotating; - #else - m_mouseState = Abstract3DController::MouseOnScene; - #endif - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; //event->pos(); - } - m_cameraHelper->updateMousePos(m_mousePos); - emitNeedRender(); -} - -void Surface3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event) - if (Abstract3DController::MouseRotating == m_mouseState) { - // update mouse positions to prevent jumping when releasing or repressing a button - m_mousePos = mousePos; //event->pos(); - m_cameraHelper->updateMousePos(mousePos); //event->pos()); - emitNeedRender(); - } - m_mouseState = Abstract3DController::MouseNone; -} - -void Surface3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) -{ - Q_UNUSED(event) - if (Abstract3DController::MouseRotating == m_mouseState) { - m_mousePos = mousePos; //event->pos(); - emitNeedRender(); - } -} - -void Surface3DController::wheelEvent(QWheelEvent *event) -{ - Q_UNUSED(event) -} - -QPoint Surface3DController::mousePosition() -{ - return m_mousePos; -} - void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy) { // Setting null proxy indicates default proxy @@ -223,4 +153,9 @@ void Surface3DController::setGradientColorAt(qreal pos, const QColor &color) emitNeedRender(); } +void Surface3DController::handleSelectionAtPoint(const QPoint &point) +{ + emit leftMousePressed(point); +} + QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/engine/surface3dcontroller_p.h b/src/datavis3d/engine/surface3dcontroller_p.h index c626a00d..3086250c 100644 --- a/src/datavis3d/engine/surface3dcontroller_p.h +++ b/src/datavis3d/engine/surface3dcontroller_p.h @@ -54,11 +54,6 @@ private: GLfloat m_segmentStep; GLfloat m_segmentMinimum; - // Interaction - MouseState m_mouseState; - QPoint m_mousePos; - QDataVis::SelectionMode m_selectionMode; - public: explicit Surface3DController(QRect rect); ~Surface3DController(); @@ -66,10 +61,6 @@ public: void initializeOpenGL(); virtual void synchDataToRenderer(); - QPoint mousePosition(); - - QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder = false); - // Enable or disable the smoothes of the surface void setSmoothSurface(bool enable); bool smoothSurface(); @@ -88,18 +79,10 @@ public: //TODO: Temp solution void setData(QList series, int width, int depth); -#if defined(Q_OS_ANDROID) - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); -#endif - void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); - void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); - void wheelEvent(QWheelEvent *event); - virtual void setActiveDataProxy(QAbstractDataProxy *proxy); virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); + void handleSelectionAtPoint(const QPoint &point); public slots: void handleArrayReset(); diff --git a/src/datavis3d/engine/surface3drenderer.cpp b/src/datavis3d/engine/surface3drenderer.cpp index 345fcc32..b1b78aec 100644 --- a/src/datavis3d/engine/surface3drenderer.cpp +++ b/src/datavis3d/engine/surface3drenderer.cpp @@ -18,7 +18,7 @@ #include "surface3dcontroller_p.h" #include "surface3drenderer_p.h" -#include "camerahelper_p.h" +#include "q3dcamera.h" #include "shaderhelper_p.h" #include "objecthelper_p.h" #include "surfaceobject_p.h" @@ -27,6 +27,7 @@ #include "theme_p.h" #include "utils_p.h" #include "drawer_p.h" +#include "q3dlight.h" #include #include @@ -208,24 +209,52 @@ void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy) Abstract3DRenderer::updateDataModel(dataProxy); } -void Surface3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle) +void Surface3DRenderer::updateScene(Q3DScene *scene) { - // Handle GL state setup for FBO buffers and clearing of the render surface - Abstract3DRenderer::render(camera, defaultFboHandle); + // TODO: Move these to more suitable place e.g. controller should be controlling the viewports. + scene->setMainViewport(m_mainViewPort); + scene->setUnderSideCameraEnabled(m_hasNegativeValues); + + // TODO: bars have m_hasHeightAdjustmentChanged, which is always true! + // Set initial camera position + // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later + scene->camera()->setDefaultOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), + QVector3D(0.0f, 0.0f, zComp), + QVector3D(0.0f, 1.0f, 0.0f)); + + // TODO: m_autoScaleAdjustment + scene->camera()->updateViewMatrix(1.0f); + scene->setLightPositionRelativeToCamera(defaultLightPos); + + Abstract3DRenderer::updateScene(scene); +} - camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp), - QVector3D(0.0f, 0.0f, zComp), - QVector3D(0.0f, 1.0f, 0.0f)); +void Surface3DRenderer::render(GLuint defaultFboHandle) +{ + m_cachedScene->setUnderSideCameraEnabled(m_hasNegativeValues); + Q3DCamera *camera = m_cachedScene->camera(); + if (defaultFboHandle) { + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } + + QVector3D clearColor = Utils::vectorFromColor(m_cachedTheme.m_windowColor); + glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - drawScene(camera, defaultFboHandle); + drawScene(defaultFboHandle); // If selection pointer is active, pass the render request for it also if (m_selectionPointer && m_selectionActive) - m_selectionPointer->render(camera, defaultFboHandle); + m_selectionPointer->render(defaultFboHandle); } -void Surface3DRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboHandle) +void Surface3DRenderer::drawScene(GLuint defaultFboHandle) { + Q3DCamera *camera = m_cachedScene->camera(); GLfloat backgroundRotation = 0; // Specify viewport @@ -237,12 +266,9 @@ void Surface3DRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f); - // Calculate view matrix - QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix( - 100.0f, //TODO: m_zoomLevel * m_autoScaleAdjustment - m_mainViewPort.width(), - m_mainViewPort.height(), - m_hasNegativeValues); + // Calculate view matrix TODO: m_autoScaleAdjustment + camera->updateViewMatrix(1.0f); + QMatrix4x4 viewMatrix = camera->viewMatrix(); // Calculate flipping indicators if (viewMatrix.row(0).x() > 0) @@ -264,7 +290,8 @@ void Surface3DRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() <= 0) backgroundRotation = 0.0f; - QVector3D lightPos = camera->calculateLightPosition(defaultLightPos); + // TODO: add 0.0f, 1.0f / m_autoScaleAdjustment + QVector3D lightPos = m_cachedScene->light()->position(); QMatrix4x4 depthViewMatrix; QMatrix4x4 depthProjectionMatrix; @@ -332,7 +359,7 @@ void Surface3DRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboH m_querySelection = false; - QPoint point = m_controller->mousePosition(); + QPoint point = m_controller->inputPosition(); GLubyte pixel[4] = {0}; glReadPixels(point.x(), m_cachedBoundingRect.height() - point.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel); @@ -1018,9 +1045,6 @@ void Surface3DRenderer::calculateSceneScalingFactors() m_scaleFactor = qMax(m_sampleSpace.width(), m_sampleSpace.height()); m_scaleX = (coordSpace * m_sampleSpace.width()) / m_scaleFactor; m_scaleZ = (coordSpace * m_sampleSpace.height()) / m_scaleFactor; - - //qDebug() << "m_scaleX" << m_scaleX << "m_scaleFactor" << m_scaleFactor; - //qDebug() << "m_scaleZ" << m_scaleZ << "m_scaleFactor" << m_scaleFactor; } void Surface3DRenderer::updateSmoothStatus(bool enable) diff --git a/src/datavis3d/engine/surface3drenderer_p.h b/src/datavis3d/engine/surface3drenderer_p.h index 4649b997..2166d9d1 100644 --- a/src/datavis3d/engine/surface3drenderer_p.h +++ b/src/datavis3d/engine/surface3drenderer_p.h @@ -52,7 +52,7 @@ class SurfaceObject; class TextureHelper; class Theme; class Drawer; -class CameraHelper; +class Q3DScene; class SelectionPointer; class QT_DATAVIS3D_EXPORT Surface3DRenderer : public Abstract3DRenderer @@ -117,7 +117,8 @@ public: ~Surface3DRenderer(); void updateDataModel(QSurfaceDataProxy *dataProxy); - void render(CameraHelper *camera, const GLuint defaultFboHandle = 0); + void updateScene(Q3DScene *scene); + void render(GLuint defaultFboHandle = 0); protected: void initializeOpenGL(); @@ -137,7 +138,7 @@ private: void loadGridLineMesh(); void loadLabelMesh(); void loadSurfaceObj(); - void drawScene(CameraHelper *camera, const GLuint defaultFboHandle); + void drawScene(GLuint defaultFboHandle); void handleResize(); void calculateSceneScalingFactors(); void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader); diff --git a/src/datavis3d/input/input.pri b/src/datavis3d/input/input.pri index 89b032da..8305604b 100644 --- a/src/datavis3d/input/input.pri +++ b/src/datavis3d/input/input.pri @@ -2,7 +2,8 @@ HEADERS += \ $$PWD/qabstract3dinputhandler.h \ $$PWD/q3dinputhandler.h \ input/qtouch3dinputhandler.h \ - input/qabstract3dinputhandler_p.h + input/qabstract3dinputhandler_p.h \ + input/q3dinputhandler_p.h SOURCES += \ $$PWD/qabstract3dinputhandler.cpp \ diff --git a/src/datavis3d/input/q3dinputhandler.cpp b/src/datavis3d/input/q3dinputhandler.cpp index 4623a69b..a8bfc19a 100644 --- a/src/datavis3d/input/q3dinputhandler.cpp +++ b/src/datavis3d/input/q3dinputhandler.cpp @@ -16,38 +16,46 @@ ** ****************************************************************************/ #include "q3dinputhandler.h" +#include "q3dcamera.h" +#include "q3dlight.h" QT_DATAVIS3D_BEGIN_NAMESPACE -Q3DInputHandler::Q3DInputHandler() : - QAbstract3DInputHandler() +Q3DInputHandler::Q3DInputHandler(QObject *parent) : + QAbstract3DInputHandler(parent) +{ +} + +Q3DInputHandler::~Q3DInputHandler() { } // Input event listeners void Q3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) { - QRect mainViewPort = mainViewPortRect(); if (Qt::LeftButton == event->button()) { - if (slicingActivated()) { - if (mousePos.x() <= mainViewPort.width() - && mousePos.y() <= mainViewPort.height()) { + if (scene()->isSlicingActivated()) { + if (scene()->isInputInsideMainView(mousePos)) { setInputState(QDataVis::InputOnOverview); //qDebug() << "Mouse pressed on overview"; - } else { + } else if (scene()->isInputInsideSliceView(mousePos)) { setInputState(QDataVis::InputOnSlice); //qDebug() << "Mouse pressed on zoom"; + } else { + setInputState(QDataVis::InputNone); } } else { setInputState(QDataVis::InputOnScene); // update mouse positions to prevent jumping when releasing or repressing a button setInputPosition(mousePos); + emit selectionAtPoint(mousePos); //qDebug() << "Mouse pressed on scene"; + } } else if (Qt::MiddleButton == event->button()) { // reset rotations setInputPosition(QPoint(0, 0)); - } else if (!slicingActivated() && Qt::RightButton == event->button()) { + } else if (Qt::RightButton == event->button()) { // disable rotating when in slice view setInputState(QDataVis::InputRotating); // update mouse positions to prevent jumping when releasing or repressing a button @@ -63,28 +71,42 @@ void Q3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mouseP if (QDataVis::InputRotating == inputState()) { // update mouse positions to prevent jumping when releasing or repressing a button setInputPosition(mousePos); - // TODO: Call actual camera class when it's been written. - //m_cameraHelper->updateMousePos(mousePos); } setInputState(QDataVis::InputNone); - } void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) { Q_UNUSED(event); - if (QDataVis::InputRotating == inputState()) + if (QDataVis::InputRotating == inputState()) { + + // Calculate mouse movement since last frame + QPointF rotations = scene()->camera()->rotations(); + GLfloat xRotation = rotations.x(); + GLfloat yRotation = rotations.y(); + GLfloat mouseMoveX = GLfloat(inputPosition().x() - mousePos.x()) + / (scene()->viewport().width() / rotationSpeed); + GLfloat mouseMoveY = GLfloat(inputPosition().y() - mousePos.y()) + / (scene()->viewport().height() / rotationSpeed); + // Apply to rotations + xRotation -= mouseMoveX; + yRotation -= mouseMoveY; + scene()->camera()->setRotations(QPointF(xRotation, yRotation)); + scene()->camera()->updateViewMatrix(1.0f); + + setPreviousInputPos(inputPosition()); setInputPosition(mousePos); + } } void Q3DInputHandler::wheelEvent(QWheelEvent *event) { // disable zooming if in slice view - if (slicingActivated()) + if (scene()->isSlicingActivated()) return; // Adjust zoom level based on what zoom range we're in. - int zoomLevel = QAbstract3DInputHandler::zoomLevel(); + int zoomLevel = scene()->camera()->zoomLevel(); if (zoomLevel > oneToOneZoomLevel) zoomLevel += event->angleDelta().y() / nearZoomRangeDivider; else if (zoomLevel > halfSizeZoomLevel) @@ -96,7 +118,7 @@ void Q3DInputHandler::wheelEvent(QWheelEvent *event) else if (zoomLevel < minZoomLevel) zoomLevel = minZoomLevel; - setZoomLevel(zoomLevel); + scene()->camera()->setZoomLevel(zoomLevel); } QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/input/q3dinputhandler.h b/src/datavis3d/input/q3dinputhandler.h index d995fe3f..98d7a047 100644 --- a/src/datavis3d/input/q3dinputhandler.h +++ b/src/datavis3d/input/q3dinputhandler.h @@ -28,20 +28,31 @@ const int nearZoomRangeDivider = 12; const int midZoomRangeDivider = 60; const int farZoomRangeDivider = 120; +const float rotationSpeed = 100.0f; + #include "qabstract3dinputhandler.h" QT_DATAVIS3D_BEGIN_NAMESPACE -class Q3DInputHandler : public QAbstract3DInputHandler +class QT_DATAVIS3D_EXPORT Q3DInputHandler : public QAbstract3DInputHandler { + Q_OBJECT + public: - explicit Q3DInputHandler(); + explicit Q3DInputHandler(QObject *parent = 0); + virtual ~Q3DInputHandler(); // Input event listeners virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos); virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos); virtual void wheelEvent(QWheelEvent *event); + +signals: + void rotationSpeedChanged(int rotationSpeed); + +private: + Q_DISABLE_COPY(Q3DInputHandler) }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/input/q3dinputhandler_p.h b/src/datavis3d/input/q3dinputhandler_p.h new file mode 100644 index 00000000..b055bd85 --- /dev/null +++ b/src/datavis3d/input/q3dinputhandler_p.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Q3DINPUTHANDLER_P_H +#define Q3DINPUTHANDLER_P_H + +#include "datavis3dglobal_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Q3DInputHandler; + +class Q3DInputHandlerPrivate +{ +public: + Q3DInputHandlerPrivate(Q3DInputHandler *q); + ~Q3DInputHandlerPrivate(); + +public: + Q3DInputHandler *q_ptr; + +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // Q3DINPUTHANDLER_P_H diff --git a/src/datavis3d/input/qabstract3dinputhandler.cpp b/src/datavis3d/input/qabstract3dinputhandler.cpp index 5155e2e2..7fb4f084 100644 --- a/src/datavis3d/input/qabstract3dinputhandler.cpp +++ b/src/datavis3d/input/qabstract3dinputhandler.cpp @@ -19,12 +19,16 @@ QT_DATAVIS3D_BEGIN_NAMESPACE -QAbstract3DInputHandler::QAbstract3DInputHandler() : - QObject(), +QAbstract3DInputHandler::QAbstract3DInputHandler(QObject *parent) : + QObject(parent), d_ptr(new QAbstract3DInputHandlerPrivate(this)) { } +QAbstract3DInputHandler::~QAbstract3DInputHandler() +{ +} + // Input event listeners void QAbstract3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event) { @@ -65,7 +69,7 @@ QDataVis::InputState QAbstract3DInputHandler::inputState() return d_ptr->m_inputState; } -void QAbstract3DInputHandler::setInputState(const QDataVis::InputState inputState) +void QAbstract3DInputHandler::setInputState(QDataVis::InputState inputState) { if (inputState != d_ptr->m_inputState) { d_ptr->m_inputState = inputState; @@ -73,12 +77,12 @@ void QAbstract3DInputHandler::setInputState(const QDataVis::InputState inputStat } } -QPoint QAbstract3DInputHandler::inputPosition() +QPoint QAbstract3DInputHandler::inputPosition() const { return d_ptr->m_inputPosition; } -void QAbstract3DInputHandler::setInputPosition(const QPoint position) +void QAbstract3DInputHandler::setInputPosition(const QPoint &position) { if (position != d_ptr->m_inputPosition) { d_ptr->m_inputPosition = position; @@ -86,72 +90,46 @@ void QAbstract3DInputHandler::setInputPosition(const QPoint position) } } -bool QAbstract3DInputHandler::slicingActivated() -{ - return d_ptr->m_isSlicingActivated; -} - -void QAbstract3DInputHandler::setSlicingActivated(const bool isSlicing) -{ - if (isSlicing != d_ptr->m_isSlicingActivated) { - d_ptr->m_isSlicingActivated = isSlicing; - emit slicingActiveChanged(isSlicing); - } -} - -int QAbstract3DInputHandler::zoomLevel() -{ - return d_ptr->m_zoomLevel; -} - -void QAbstract3DInputHandler::setZoomLevel(const int zoomLevel) -{ - if (zoomLevel != d_ptr->m_zoomLevel) { - d_ptr->m_zoomLevel = zoomLevel; - emit zoomLevelChanged(zoomLevel); - } -} - void QAbstract3DInputHandler::setPrevDistance(int distance) { d_ptr->m_prevDistance = distance; } -int QAbstract3DInputHandler::prevDistance() +int QAbstract3DInputHandler::prevDistance() const { return d_ptr->m_prevDistance; } -QRect QAbstract3DInputHandler::mainViewPortRect() +Q3DScene *QAbstract3DInputHandler::scene() const { - return d_ptr->m_mainViewPort; + return d_ptr->m_scene; } -void QAbstract3DInputHandler::setMainViewPortRect(const QRect viewPort) +void QAbstract3DInputHandler::setScene(Q3DScene *scene) { - d_ptr->m_mainViewPort = viewPort; + d_ptr->m_scene = scene; } -CameraHelper *QAbstract3DInputHandler::camera() +void QAbstract3DInputHandler::setPreviousInputPos(const QPoint &position) { - return d_ptr->m_camera; + d_ptr->m_previousInputPos = position; } -void QAbstract3DInputHandler::setCamera(CameraHelper *camera) +QPoint QAbstract3DInputHandler::previousInputPos() const { - d_ptr->m_camera = camera; + return d_ptr->m_previousInputPos; } + QAbstract3DInputHandlerPrivate::QAbstract3DInputHandlerPrivate(QAbstract3DInputHandler *q) : q_ptr(q), m_prevDistance(0), m_inputState(QDataVis::InputNone), - m_isSlicingActivated(false), m_inputPosition(QPoint(0,0)), - m_zoomLevel(0), - m_camera(0) + m_previousInputPos(QPoint(0,0)), + m_scene(0) { } diff --git a/src/datavis3d/input/qabstract3dinputhandler.h b/src/datavis3d/input/qabstract3dinputhandler.h index 5d98afa1..03c46a5e 100644 --- a/src/datavis3d/input/qabstract3dinputhandler.h +++ b/src/datavis3d/input/qabstract3dinputhandler.h @@ -19,29 +19,24 @@ #ifndef QABSTRACT3DINPUTHANDLER_H #define QABSTRACT3DINPUTHANDLER_H -#include - #include "qdatavis3denums.h" #include "qabstract3dinputhandler_p.h" +#include "q3dscene.h" +#include +#include QT_DATAVIS3D_BEGIN_NAMESPACE -class QAbstract3DInputHandler : public QObject +class QT_DATAVIS3D_EXPORT QAbstract3DInputHandler : public QObject { Q_OBJECT Q_PROPERTY(QtDataVis3D::QDataVis::InputState inputState READ inputState WRITE setInputState NOTIFY inputStateChanged) Q_PROPERTY(QPoint inputPosition READ inputPosition WRITE setInputPosition NOTIFY positionChanged) - Q_PROPERTY(bool slicingActivated READ slicingActivated WRITE setSlicingActivated NOTIFY slicingActiveChanged) - Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged) - Q_PROPERTY(QRect mainViewPortRect READ mainViewPortRect WRITE setMainViewPortRect) - - Q_PROPERTY(CameraHelper *camera READ camera WRITE setCamera) - -private: - QScopedPointer d_ptr; + Q_PROPERTY(Q3DScene *scene READ scene WRITE setScene) public: - explicit QAbstract3DInputHandler(); + explicit QAbstract3DInputHandler(QObject *parent = 0); + virtual ~QAbstract3DInputHandler(); // Input event listeners virtual void mouseDoubleClickEvent(QMouseEvent *event); @@ -56,29 +51,30 @@ public: // TODO: Check if the inputState needs to be visible outside of subclasses in the final architecture QDataVis::InputState inputState(); - void setInputState(const QDataVis::InputState inputState); - void setInputPosition(const QPoint position); - QPoint inputPosition(); - void setSlicingActivated(const bool isSlicing); - bool slicingActivated(); - void setZoomLevel(const int zoomLevel); - int zoomLevel(); - QRect mainViewPortRect(); - void setMainViewPortRect(const QRect viewPort); - - // TODO: Modify for proper camera once that is available - CameraHelper *camera(); - void setCamera(CameraHelper *camera); + void setInputState(QDataVis::InputState inputState); + void setInputPosition(const QPoint &position); + QPoint inputPosition() const; + + Q3DScene *scene() const; + void setScene(Q3DScene *scene); protected: void setPrevDistance(int distance); - int prevDistance(); + int prevDistance() const; + void setPreviousInputPos(const QPoint &position); + QPoint previousInputPos() const; signals: - void positionChanged(QPoint position); + void positionChanged(const QPoint &position); void inputStateChanged(QDataVis::InputState state); - void slicingActiveChanged(bool isSlicing); - void zoomLevelChanged(int zoomLevel); + void selectionAtPoint(const QPoint &point); + +private: + Q_DISABLE_COPY(QAbstract3DInputHandler) + + QScopedPointer d_ptr; + + friend class Abstract3DController; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/input/qabstract3dinputhandler_p.h b/src/datavis3d/input/qabstract3dinputhandler_p.h index 7c56c2fa..a4b61ff3 100644 --- a/src/datavis3d/input/qabstract3dinputhandler_p.h +++ b/src/datavis3d/input/qabstract3dinputhandler_p.h @@ -29,12 +29,13 @@ #ifndef QABSTRACT3DINPUTHANDLER_P_H #define QABSTRACT3DINPUTHANDLER_P_H -#include +#include "datavis3dglobal_p.h" +#include QT_DATAVIS3D_BEGIN_NAMESPACE class QAbstract3DInputHandler; -class CameraHelper; +class Q3DScene; class QAbstract3DInputHandlerPrivate { @@ -45,18 +46,22 @@ public: public: QAbstract3DInputHandler *q_ptr; int m_prevDistance; + QPoint m_previousInputPos; + + GLfloat m_defaultXRotation; + GLfloat m_defaultYRotation; private: QDataVis::InputState m_inputState; - bool m_isSlicingActivated; QPoint m_inputPosition; - int m_zoomLevel; QRect m_mainViewPort; - // TODO: Replace with proper camera once it's available - CameraHelper *m_camera; + // TODO: Check if this could be avoided with signals/slots or some other way. + Q3DScene *m_scene; + bool m_isDefaultHandler; friend class QAbstract3DInputHandler; + friend class Abstract3DController; }; QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/input/qtouch3dinputhandler.cpp b/src/datavis3d/input/qtouch3dinputhandler.cpp index 128b8c49..d0676719 100644 --- a/src/datavis3d/input/qtouch3dinputhandler.cpp +++ b/src/datavis3d/input/qtouch3dinputhandler.cpp @@ -16,18 +16,23 @@ ** ****************************************************************************/ #include "qtouch3dinputhandler.h" +#include "q3dcamera.h" QT_DATAVIS3D_BEGIN_NAMESPACE -QTouch3DInputHandler::QTouch3DInputHandler() : - Q3DInputHandler() +QTouch3DInputHandler::QTouch3DInputHandler(QObject *parent) : + Q3DInputHandler(parent) +{ +} + +QTouch3DInputHandler::~QTouch3DInputHandler() { } // Input event listeners void QTouch3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event) { - if (!slicingActivated()) { + if (!scene()->isSlicingActivated()) { setInputState( QDataVis::InputOnScene ); // update mouse positions to prevent jumping when releasing or repressing a button setInputPosition( event->pos() ); @@ -39,13 +44,13 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event) QList points; points = event->touchPoints(); - if (!slicingActivated() && points.count() == 2) { + if (!scene()->isSlicingActivated() && points.count() == 2) { setInputState( QDataVis::InputOnPinch ); QPointF distance = points.at(0).pos() - points.at(1).pos(); int newDistance = distance.manhattanLength(); int zoomRate = 1; - int zoomLevel = QAbstract3DInputHandler::zoomLevel(); + int zoomLevel = scene()->camera()->zoomLevel(); if (zoomLevel > 100) zoomRate = 5; if (newDistance > prevDistance()) @@ -56,7 +61,7 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event) zoomLevel = 500; else if (zoomLevel < 10) zoomLevel = 10; - setZoomLevel(zoomLevel); + scene()->camera()->setZoomLevel(zoomLevel); setPrevDistance(newDistance); } } @@ -64,16 +69,16 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event) void QTouch3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) { // TODO: This code needs revisiting with new Qt releases and possibly move to using touch events for these as well. - QRect mainViewPort = mainViewPortRect(); if (Qt::LeftButton == event->button()) { - if (slicingActivated()) { - if (mousePos.x() <= mainViewPort.width() - && mousePos.y() <= mainViewPort.height()) { + if (scene()->isSlicingActivated()) { + if (scene()->isInputInsideMainView(mousePos)) { setInputState(QDataVis::InputOnOverview); //qDebug() << "Mouse pressed on overview"; - } else { + } else if (scene()->isInputInsideSliceView(mousePos)) { setInputState(QDataVis::InputOnSlice); //qDebug() << "Mouse pressed on zoom"; + } else { + setInputState(QDataVis::InputNone); } } else { setInputState(QDataVis::InputRotating); @@ -84,14 +89,12 @@ void QTouch3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mou } else if (Qt::MiddleButton == event->button()) { // reset rotations setInputPosition(QPoint(0, 0)); - } else if (!slicingActivated() && Qt::RightButton == event->button()) { + } else if (Qt::RightButton == event->button()) { // disable rotating when in slice view setInputState(QDataVis::InputOnScene); // update mouse positions to prevent jumping when releasing or repressing a button setInputPosition(mousePos); } - // TODO: Call actual camera class when it's been written. - //m_cameraHelper->updateMousePos(m_mousePos); } QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/input/qtouch3dinputhandler.h b/src/datavis3d/input/qtouch3dinputhandler.h index a56f82ce..4b2dad69 100644 --- a/src/datavis3d/input/qtouch3dinputhandler.h +++ b/src/datavis3d/input/qtouch3dinputhandler.h @@ -23,17 +23,21 @@ QT_DATAVIS3D_BEGIN_NAMESPACE -class QTouch3DInputHandler : public Q3DInputHandler +class QT_DATAVIS3D_EXPORT QTouch3DInputHandler : public Q3DInputHandler { Q_OBJECT public: - explicit QTouch3DInputHandler(); + explicit QTouch3DInputHandler(QObject *parent = 0); + virtual ~QTouch3DInputHandler(); // Input event listeners virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void touchEvent(QTouchEvent *event); virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); + +private: + Q_DISABLE_COPY(QTouch3DInputHandler) }; QT_DATAVIS3D_END_NAMESPACE -- cgit v1.2.3