summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/datavis3d/engine/abstract3dcontroller.cpp189
-rw-r--r--src/datavis3d/engine/abstract3dcontroller_p.h39
-rw-r--r--src/datavis3d/engine/abstract3drenderer.cpp28
-rw-r--r--src/datavis3d/engine/abstract3drenderer_p.h15
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp183
-rw-r--r--src/datavis3d/engine/bars3dcontroller_p.h20
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp121
-rw-r--r--src/datavis3d/engine/bars3drenderer_p.h14
-rw-r--r--src/datavis3d/engine/drawer.cpp6
-rw-r--r--src/datavis3d/engine/drawer_p.h4
-rw-r--r--src/datavis3d/engine/engine.pri18
-rw-r--r--src/datavis3d/engine/q3dbox.cpp480
-rw-r--r--src/datavis3d/engine/q3dbox.h184
-rw-r--r--src/datavis3d/engine/q3dcamera.cpp295
-rw-r--r--src/datavis3d/engine/q3dcamera.h87
-rw-r--r--src/datavis3d/engine/q3dcamera_p.h61
-rw-r--r--src/datavis3d/engine/q3dlight.cpp49
-rw-r--r--src/datavis3d/engine/q3dlight.h50
-rw-r--r--src/datavis3d/engine/q3dlight_p.h57
-rw-r--r--src/datavis3d/engine/q3dobject.cpp73
-rw-r--r--src/datavis3d/engine/q3dobject.h54
-rw-r--r--src/datavis3d/engine/q3dobject_p.h53
-rw-r--r--src/datavis3d/engine/q3dscene.cpp199
-rw-r--r--src/datavis3d/engine/q3dscene.h83
-rw-r--r--src/datavis3d/engine/q3dscene_p.h60
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp154
-rw-r--r--src/datavis3d/engine/scatter3dcontroller_p.h23
-rw-r--r--src/datavis3d/engine/scatter3drenderer.cpp99
-rw-r--r--src/datavis3d/engine/scatter3drenderer_p.h9
-rw-r--r--src/datavis3d/engine/selectionpointer.cpp27
-rw-r--r--src/datavis3d/engine/selectionpointer_p.h7
-rw-r--r--src/datavis3d/engine/surface3dcontroller.cpp81
-rw-r--r--src/datavis3d/engine/surface3dcontroller_p.h19
-rw-r--r--src/datavis3d/engine/surface3drenderer.cpp66
-rw-r--r--src/datavis3d/engine/surface3drenderer_p.h7
-rw-r--r--src/datavis3d/input/input.pri3
-rw-r--r--src/datavis3d/input/q3dinputhandler.cpp52
-rw-r--r--src/datavis3d/input/q3dinputhandler.h15
-rw-r--r--src/datavis3d/input/q3dinputhandler_p.h51
-rw-r--r--src/datavis3d/input/qabstract3dinputhandler.cpp64
-rw-r--r--src/datavis3d/input/qabstract3dinputhandler.h54
-rw-r--r--src/datavis3d/input/qabstract3dinputhandler_p.h17
-rw-r--r--src/datavis3d/input/qtouch3dinputhandler.cpp31
-rw-r--r--src/datavis3d/input/qtouch3dinputhandler.h8
44 files changed, 2439 insertions, 770 deletions
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<Abstract3DController *>(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<QAbstract3DInputHandler *> 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<Q3DAbstractAxis *> 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<QTouchEvent::TouchPoint> 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 <QMatrix4x4>
#include <QMouseEvent>
@@ -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 <QMatrix4x4>
@@ -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 <QtGui/QMatrix4x4>
+#include <QtCore/QList>
+
+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 <qmath.h>
+#include <QVector3D>
+
+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 <QObject>
+#include <QMatrix4x4>
+
+#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<Q3DCameraPrivate> 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 <QObject>
+
+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 <QObject>
+
+#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<Q3DLightPrivate> 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 <QObject>
+#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<Q3DObjectPrivate> 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 <qmath.h>
+
+#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 <QObject>
+
+#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<Q3DScenePrivate> 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 <QRect>
+
+#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<QTouchEvent::TouchPoint> 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 <QMatrix4x4>
#include <QMouseEvent>
@@ -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 <QImage>
#include <QMatrix4x4>
@@ -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 <QWindow>
#include <QVector3D>
+#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<qreal> 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 <QMatrix4x4>
#include <QMouseEvent>
@@ -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 <QObject>
-
#include "qdatavis3denums.h"
#include "qabstract3dinputhandler_p.h"
+#include "q3dscene.h"
+#include <QObject>
+#include <QMouseEvent>
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<QAbstract3DInputHandlerPrivate> 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<QAbstract3DInputHandlerPrivate> 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 <QMouseEvent>
+#include "datavis3dglobal_p.h"
+#include <QRect>
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<QTouchEvent::TouchPoint> 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