summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorKeränen Pasi <pasi.keranen@digia.com>2013-09-13 11:13:16 +0300
committerPasi Keränen <pasi.keranen@digia.com>2013-09-19 12:11:33 +0300
commit802681d854d93a50547585570da3bcf7b6c41636 (patch)
tree2818f239df688f6ad5b91b2ac9d638ffae34e24a /src/datavisualization
parent35a5a5302fdcf43bc571f51f03512e3df9d2c58c (diff)
Qdoc documentation for new scene and input classes.
Change-Id: I5d9680fcf2e49655c1b9bcdf961bbda02bf31968 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com> Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp36
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h8
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp16
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp59
-rw-r--r--src/datavisualization/engine/q3dcamera.cpp189
-rw-r--r--src/datavisualization/engine/q3dcamera.h31
-rw-r--r--src/datavisualization/engine/q3dcamera_p.h10
-rw-r--r--src/datavisualization/engine/q3dlight.cpp23
-rw-r--r--src/datavisualization/engine/q3dobject.cpp54
-rw-r--r--src/datavisualization/engine/q3dobject.h5
-rw-r--r--src/datavisualization/engine/q3dobject_p.h1
-rw-r--r--src/datavisualization/engine/q3dscene.cpp224
-rw-r--r--src/datavisualization/engine/q3dscene.h44
-rw-r--r--src/datavisualization/engine/q3dscene_p.h14
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp31
-rw-r--r--src/datavisualization/engine/selectionpointer.cpp5
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp65
-rw-r--r--src/datavisualization/input/q3dinputhandler.cpp59
-rw-r--r--src/datavisualization/input/q3dinputhandler.h3
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.cpp81
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.h18
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler.cpp45
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler.h1
23 files changed, 687 insertions, 335 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index e9ba1739..7c98f804 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -62,7 +62,7 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) :
m_theme.useColorTheme(QDataVis::ThemeSystem);
// Populate the scene
- m_scene->light()->setPosition(defaultLightPos);
+ m_scene->activeLight()->setPosition(defaultLightPos);
// Create initial default input handler
QAbstract3DInputHandler *inputHandler;
@@ -428,24 +428,24 @@ int Abstract3DController::y()
return m_boundingRect.y();
}
-QRect Abstract3DController::mainViewport() const
+QRect Abstract3DController::primarySubViewport() const
{
- return m_scene->mainViewport();
+ return m_scene->primarySubViewport();
}
-void Abstract3DController::setMainViewport(const QRect &mainViewport)
+void Abstract3DController::setPrimarySubViewport(const QRect &primarySubViewport)
{
- m_scene->setMainViewport(mainViewport);
+ m_scene->setPrimarySubViewport(primarySubViewport);
}
-QRect Abstract3DController::sliceViewport() const
+QRect Abstract3DController::secondarySubViewport() const
{
- return m_scene->sliceViewport();
+ return m_scene->secondarySubViewport();
}
-void Abstract3DController::setSliceViewport(const QRect &sliceViewport)
+void Abstract3DController::setSecondarySubViewport(const QRect &secondarySubViewport)
{
- m_scene->setSliceViewport(sliceViewport);
+ m_scene->setSecondarySubViewport(secondarySubViewport);
}
void Abstract3DController::setAxisX(Q3DAbstractAxis *axis)
@@ -636,12 +636,12 @@ QAbstract3DInputHandler* Abstract3DController::activeInputHandler()
int Abstract3DController::zoomLevel()
{
- return m_scene->camera()->zoomLevel();
+ return m_scene->activeCamera()->zoomLevel();
}
void Abstract3DController::setZoomLevel(int zoomLevel)
{
- m_scene->camera()->setZoomLevel(zoomLevel);
+ m_scene->activeCamera()->setZoomLevel(zoomLevel);
m_changeTracker.zoomLevelChanged = true;
emitNeedRender();
@@ -649,25 +649,25 @@ void Abstract3DController::setZoomLevel(int zoomLevel)
void Abstract3DController::setCameraPreset(QDataVis::CameraPreset preset)
{
- m_scene->camera()->setCameraPreset(preset);
+ m_scene->activeCamera()->setCameraPreset(preset);
emitNeedRender();
}
QDataVis::CameraPreset Abstract3DController::cameraPreset() const
{
- return m_scene->camera()->cameraPreset();
+ return m_scene->activeCamera()->cameraPreset();
}
void Abstract3DController::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
{
// disable camera movement if in slice view
- if (scene()->isSlicingActivated())
+ if (scene()->isSlicingActive())
return;
m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
m_verticalRotation = qBound(0.0f, vertical, 90.0f);
- m_scene->camera()->setZoomLevel(qBound(10, distance, 500));
- m_scene->camera()->setRotations(QPointF(m_horizontalRotation,
+ m_scene->activeCamera()->setZoomLevel(qBound(10, distance, 500));
+ m_scene->activeCamera()->setRotations(QPointF(m_horizontalRotation,
m_verticalRotation));
//qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation;
emitNeedRender();
@@ -778,12 +778,12 @@ bool Abstract3DController::gridEnabled()
bool Abstract3DController::isSlicingActive()
{
- return m_scene->isSlicingActivated();
+ return m_scene->isSlicingActive();
}
void Abstract3DController::setSlicingActive(bool isSlicing)
{
- m_scene->setSlicingActivated(isSlicing);
+ m_scene->setSlicingActive(isSlicing);
emitNeedRender();
}
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index c08a7cab..1ad50f18 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -209,11 +209,11 @@ public:
virtual void setY(const int y);
virtual int y();
- virtual QRect mainViewport() const;
- virtual void setMainViewport(const QRect &mainViewport);
+ virtual QRect primarySubViewport() const;
+ virtual void setPrimarySubViewport(const QRect &primarySubViewport);
- virtual QRect sliceViewport() const;
- virtual void setSliceViewport(const QRect &sliceViewport);
+ virtual QRect secondarySubViewport() const;
+ virtual void setSecondarySubViewport(const QRect &secondarySubViewport);
virtual void setAxisX(Q3DAbstractAxis *axis);
virtual Q3DAbstractAxis *axisX();
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 5ec6f01f..cff730e7 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -137,7 +137,7 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
void Bars3DController::handleArrayReset()
{
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
// Clear selection unless still valid
@@ -150,7 +150,7 @@ void Bars3DController::handleRowsAdded(int startIndex, int count)
Q_UNUSED(startIndex)
Q_UNUSED(count)
// TODO should update slice instead of deactivating?
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -161,7 +161,7 @@ void Bars3DController::handleRowsChanged(int startIndex, int count)
Q_UNUSED(startIndex)
Q_UNUSED(count)
// TODO should update slice instead of deactivating?
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -172,7 +172,7 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count)
Q_UNUSED(startIndex)
Q_UNUSED(count)
// TODO should update slice instead of deactivating?
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
@@ -187,7 +187,7 @@ void Bars3DController::handleRowsInserted(int startIndex, int count)
Q_UNUSED(startIndex)
Q_UNUSED(count)
// TODO should update slice instead of deactivating?
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -198,7 +198,7 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex)
Q_UNUSED(rowIndex)
Q_UNUSED(columnIndex)
// TODO should update slice instead of deactivating?
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
adjustAxisRanges();
m_isDataDirty = true;
emitNeedRender();
@@ -269,7 +269,7 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender)
// Data window changed
if (sender == m_axisX || sender == m_axisZ) {
// Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
// Clear selection unless still valid
setSelectedBarPos(m_selectedBarPos);
@@ -331,7 +331,7 @@ void Bars3DController::setBarType(QDataVis::MeshStyle style, bool smooth)
void Bars3DController::setSelectionMode(QDataVis::SelectionMode mode)
{
// Disable zoom if selection mode changes
- scene()->setSlicingActivated(false);
+ scene()->setSlicingActive(false);
Abstract3DController::setSelectionMode(mode);
}
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index adc3c257..edb0d971 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -18,7 +18,7 @@
#include "bars3drenderer_p.h"
#include "bars3dcontroller_p.h"
-#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "texturehelper_p.h"
@@ -209,18 +209,18 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy)
void Bars3DRenderer::updateScene(Q3DScene *scene)
{
// TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
- scene->setSliceViewport(m_sliceViewPort);
- scene->setMainViewport(m_mainViewPort);
+ scene->setSecondarySubViewport(m_sliceViewPort);
+ scene->setPrimarySubViewport(m_mainViewPort);
scene->setUnderSideCameraEnabled(m_hasNegativeValues);
if (m_hasHeightAdjustmentChanged) {
// Set initial camera position. Also update if height adjustment has changed.
- scene->camera()->setDefaultOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
- QVector3D(0.0f, -m_yAdjustment, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
+ scene->activeCamera()->setBaseOrientation(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);
+ scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
// Set light position (rotate light with camera, a bit above it (as set in defaultLightPos))
scene->setLightPositionRelativeToCamera(defaultLightPos);
@@ -229,7 +229,7 @@ void Bars3DRenderer::updateScene(Q3DScene *scene)
void Bars3DRenderer::render(GLuint defaultFboHandle)
{
- bool slicingActivated = m_cachedScene->isSlicingActivated();
+ bool slicingActivated = m_cachedScene->isSlicingActive();
updateSlicingActive(slicingActivated);
// Handle GL state setup for FBO buffers and clearing of the render surface
@@ -243,7 +243,7 @@ void Bars3DRenderer::render(GLuint defaultFboHandle)
drawScene(defaultFboHandle);
// If slicing has been activated by this render pass, we need another render
- if (slicingActivated != m_cachedScene->isSlicingActivated())
+ if (slicingActivated != m_cachedScene->isSlicingActive())
emit needRender();
}
@@ -375,37 +375,32 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
- Drawer::LabelTop);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelTop);
}
m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
- Drawer::LabelBottom);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelBottom);
} else {
m_drawer->drawLabel(*dummyItem, xLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
- Drawer::LabelBottom);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelBottom);
if (m_sliceTitleItem) {
m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
- Drawer::LabelTop);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelTop);
}
}
m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 90.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
- Drawer::LabelLeft);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelLeft);
// Draw labels for bars
for (int col = 0; col < m_sliceSelection->size(); col++) {
@@ -417,7 +412,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D(0.0f, 0.0f, 90.0f),
item->height(),
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
+ m_labelObj, m_cachedScene->activeCamera(), false, false,
Drawer::LabelOver, Qt::AlignTop);
} else {
m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix,
@@ -425,7 +420,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D(0.0f, 0.0f, 0.0f),
negativesComp * negativesComp * item->height(),
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera());
+ m_labelObj, m_cachedScene->activeCamera());
}
// Draw labels
@@ -436,7 +431,7 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, -45.0f), item->height(),
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), false, false,
+ m_labelObj, m_cachedScene->activeCamera(), false, false,
Drawer::LabelBelow);
}
}
@@ -475,7 +470,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
/ (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
// Get the view matrix
- QMatrix4x4 viewMatrix = m_cachedScene->camera()->viewMatrix();
+ QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->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)
@@ -519,7 +514,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
backgroundRotation = 0.0f;
// Get light position from the scene
- QVector3D lightPos = m_cachedScene->light()->position();
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
// Skip depth rendering if we're in slice mode
// Introduce regardless of shadow quality to simplify logic
@@ -543,7 +538,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
// Get the depth view matrix
// It may be possible to hack lightPos here if we want to make some tweaks to shadow
- QVector3D depthLightPos = m_cachedScene->camera()->calculatePositionRelativeToCamera(
+ QVector3D depthLightPos = m_cachedScene->activeCamera()->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));
@@ -1277,7 +1272,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
}
@@ -1315,7 +1310,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
}
@@ -1364,7 +1359,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
// Side wall
@@ -1385,7 +1380,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
@@ -1399,11 +1394,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
if (m_cachedIsSlicingActivated
&& (m_selection == selectionSkipColor
|| QDataVis::InputOnOverview == m_controller->inputState())) {
- m_cachedScene->setSlicingActivated(false);
+ m_cachedScene->setSlicingActive(false);
}
} else if (m_cachedSelectionMode >= QDataVis::ModeSliceRow && selectionDirty) {
// Activate slice mode
- m_cachedScene->setSlicingActivated(true);
+ m_cachedScene->setSlicingActive(true);
// Create label textures
for (int col = 0; col < m_sliceSelection->size(); col++) {
@@ -1466,7 +1461,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), selectedBar->height(),
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), true, false);
+ m_labelObj, m_cachedScene->activeCamera(), true, false);
// Reset label update flag; they should have been updated when we get here
m_updateLabels = false;
diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp
index 4b1ca81f..229657fd 100644
--- a/src/datavisualization/engine/q3dcamera.cpp
+++ b/src/datavisualization/engine/q3dcamera.cpp
@@ -27,16 +27,38 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+/*!
+ \class Q3DCamera
+ \inmodule QtDataVisualization
+ \brief Representation of a camera in 3D space.
+ \since 1.0.0
+
+ Q3DCamera represents a basic orbit around centerpoint 3D camera that is used when rendering the data visualization.
+ The class offers simple methods for setting the orbit point in rotations, but allows also setting the 4x4 viewmatrix
+ directly in case a more customized camera behavior is needed.
+*/
+
+/*!
+ * Constructs a new 3D camera with position set to origo, up direction facing towards the Y-axis and looking at origo by default. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
Q3DCamera::Q3DCamera(QObject *parent) :
Q3DObject(parent),
d_ptr(new Q3DCameraPrivate(this))
{
}
+/*!
+ * Destroys the camera object.
+ */
Q3DCamera::~Q3DCamera()
{
}
+/*!
+ * Copies the 3D camera's properties from the given source camera.
+ * Values are copied from the \a source to this object.
+ */
void Q3DCamera::copyValuesFrom(const Q3DCamera &source)
{
Q3DObject::copyValuesFrom(source);
@@ -61,6 +83,18 @@ void Q3DCamera::copyValuesFrom(const Q3DCamera &source)
d_ptr->m_activePreset = source.d_ptr->m_activePreset;
}
+/*!
+ * \property Q3DCamera::rotations
+ *
+ * This property contains the rotation angles of the camera around the target point in degrees starting from
+ * the current base position set by the setBaseOrientation() methods.
+ */
+QPointF Q3DCamera::rotations() const
+{
+ QPointF rotations(d_ptr->m_xRotation, d_ptr->m_yRotation);
+ return rotations;
+}
+
void Q3DCamera::setRotations(const QPointF &rotation)
{
d_ptr->setRotations(rotation);
@@ -70,24 +104,36 @@ void Q3DCamera::setRotations(const QPointF &rotation)
}
}
-void Q3DCamera::setDefaultOrientation(const QVector3D &defaultPosition,
- const QVector3D &defaultTarget,
- const QVector3D &defaultUp)
+/*!
+ * Sets the base values for the camera that are used when calculating the camera position using the rotation values.
+ * The base position of the camera is defined by \a basePosition, expectation is that the x and y values are 0.
+ * Look at target point is defined by \a target and the camera rotates around it. Up direction for the camera is
+ * defined by \a baseUp, normally this is a vector with only y values set to 1.
+ */
+void Q3DCamera::setBaseOrientation(const QVector3D &basePosition,
+ const QVector3D &target,
+ const QVector3D &baseUp)
{
- if (position() != defaultPosition
- || d_ptr->m_target != defaultTarget
- || d_ptr->m_up != defaultUp) {
- setPosition(defaultPosition);
- d_ptr->m_target = defaultTarget;
- d_ptr->m_up = defaultUp;
+ if (position() != basePosition
+ || d_ptr->m_target != target
+ || d_ptr->m_up != baseUp) {
+ setPosition(basePosition);
+ d_ptr->m_target = target;
+ d_ptr->m_up = baseUp;
setDirty(true);
}
}
-QPointF Q3DCamera::rotations() const
+/*!
+ * \property Q3DCamera::viewMatrix
+ *
+ * This property contains the view matrix used in the 3D calculations. When the default orbiting camera behavior is sufficient
+ * there is no need to touch this property. But if the default behavior is insufficient the view matrix can be set directly.
+ * When setting the view matrix directly remember to set Q3DCamera::viewMatrixAutoUpdateEnabled to false.
+ */
+QMatrix4x4 Q3DCamera::viewMatrix() const
{
- QPointF rotations(d_ptr->m_xRotation, d_ptr->m_yRotation);
- return rotations;
+ return d_ptr->m_viewMatrix;
}
void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix)
@@ -98,46 +144,31 @@ void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix)
}
}
-QMatrix4x4 Q3DCamera::viewMatrix() const
+/*!
+ * \property Q3DCamera::viewMatrixAutoUpdateEnabled
+ *
+ * This property determines if view matrix is automatically updated each render cycle using the current base orientation and
+ * rotations. If set to false, no automatic recalculation is done and the view matrix can be set using the
+ * Q3DMatrix::viewMatrix property.
+ */
+bool Q3DCamera::isViewMatrixAutoUpdateEnabled()
{
- return d_ptr->m_viewMatrix;
+ return d_ptr->m_isViewMatrixUpdateActive;
}
-void Q3DCamera::updateViewMatrix(qreal zoomAdjustment)
+void Q3DCamera::setViewMatrixAutoUpdateEnabled(bool isEnabled)
{
- 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);
+ d_ptr->m_isViewMatrixUpdateActive = isEnabled;
}
+/*!
+ * \property Q3DCamera::cameraPreset
+ *
+ * This property contains the currently active camera preset,
+ * if no preset is active the value is QDataVis::NoPreset.
+ * \note The base camera orientation set by setBaseOrientation() will affect
+ * the presets as all calculations are based on those values.
+ */
QDataVis::CameraPreset Q3DCamera::cameraPreset()
{
return d_ptr->m_activePreset;
@@ -253,6 +284,17 @@ void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset)
}
}
+/*!
+ * \property Q3DCamera::zoomLevel
+ *
+ * This property contains the the camera zoom level in percentages.
+ * 100% means there is no zoom in or out set in the camera.
+ */
+int Q3DCamera::zoomLevel()
+{
+ return d_ptr->m_zoomLevel;
+}
+
void Q3DCamera::setZoomLevel(int zoomLevel)
{
if (d_ptr->m_zoomLevel != zoomLevel) {
@@ -261,11 +303,14 @@ void Q3DCamera::setZoomLevel(int zoomLevel)
}
}
-int Q3DCamera::zoomLevel()
-{
- return d_ptr->m_zoomLevel;
-}
-
+/*!
+ * Calculates and returns a position relative to the camera using the given parameters
+ * and the current camera viewMatrix property.
+ * \a relativePosition defines the relative 3D offset to the current camera position.
+ * \a fixedRotation is optional, if given fixes rotation of the calculated point around the data visualization area to the given value in degrees.
+ * \a distanceModifier is also optional, if given modifies the distance of the calculated point from the data visualization.
+ * \return Calculated position relative to this camera's position.
+ */
QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relativePosition,
qreal fixedRotation,
qreal distanceModifier) const
@@ -294,6 +339,7 @@ QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relative
Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) :
q_ptr(q),
+ m_isViewMatrixUpdateActive(true),
m_xRotation(0.0f),
m_yRotation(0.0f),
m_zoomLevel(100),
@@ -326,4 +372,45 @@ void Q3DCameraPrivate::setRotations(const QPointF &rotation)
}
}
+// Recalculates the view matrix based on the currently set base orientation, rotation and zoom level values.
+// zoomAdjustment is adjustment to ensure that the 3D visualization stays inside the view area in the 100% zoom.
+void Q3DCameraPrivate::updateViewMatrix(qreal zoomAdjustment)
+{
+ if (!m_isViewMatrixUpdateActive)
+ return;
+
+ bool showUnder = q_ptr->parentScene()->isUnderSideCameraEnabled();
+ int zoom = m_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(m_xRotation) >= 360.0f)
+ m_xRotation = 0.0f;
+ if (m_yRotation >= 90.0f)
+ m_yRotation = 90.0f;
+ else if (m_yRotation <= lowerLimit)
+ m_yRotation = lowerLimit;
+
+ // Apply to view matrix
+ viewMatrix.lookAt(q_ptr->position(), m_target, m_up);
+ // Compensate for translation (if d_ptr->m_target is off origin)
+ viewMatrix.translate(m_target.x(), m_target.y(), m_target.z());
+ // Apply rotations
+ // Handle x and z rotation when y -angle is other than 0
+ viewMatrix.rotate(m_xRotation, 0, qCos(qDegreesToRadians(m_yRotation)),
+ qSin(qDegreesToRadians(m_yRotation)));
+ // y rotation is always "clean"
+ viewMatrix.rotate(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(-m_target.x(), -m_target.y(), -m_target.z());
+
+ q_ptr->setViewMatrix(viewMatrix);
+}
+
+
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h
index 2db4b300..60910786 100644
--- a/src/datavisualization/engine/q3dcamera.h
+++ b/src/datavisualization/engine/q3dcamera.h
@@ -37,7 +37,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DCamera : public Q3DObject
Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix)
Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset)
Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel)
-
+ Q_PROPERTY(bool viewMatrixAutoUpdateEnabled READ isViewMatrixAutoUpdateEnabled WRITE setViewMatrixAutoUpdateEnabled)
public:
Q3DCamera(QObject *parent = 0);
@@ -45,27 +45,24 @@ public:
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 setRotations(const QPointF &rotation);
- virtual void setViewMatrix(const QMatrix4x4 &viewMatrix);
virtual QMatrix4x4 viewMatrix() const;
+ virtual void setViewMatrix(const QMatrix4x4 &viewMatrix);
- // 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(qreal zoomAdjustment);
+ virtual bool isViewMatrixAutoUpdateEnabled();
+ virtual void setViewMatrixAutoUpdateEnabled(bool isEnabled);
- virtual void setCameraPreset(QDataVis::CameraPreset preset);
virtual QDataVis::CameraPreset cameraPreset();
+ virtual void setCameraPreset(QDataVis::CameraPreset preset);
- virtual void setZoomLevel(int zoomLevel);
virtual int zoomLevel();
+ virtual void setZoomLevel(int zoomLevel);
+
+ virtual void setBaseOrientation(const QVector3D &defaultPosition,
+ const QVector3D &defaultTarget,
+ const QVector3D &defaultUp);
virtual QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition,
qreal fixedRotation,
@@ -78,6 +75,12 @@ private:
friend class Q3DCameraPrivate;
friend class Q3DScenePrivate;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class SelectionPointer;
+ friend class Q3DInputHandler;
+ friend class QMac3DInputHandler;
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h
index 14556116..cf6e9c66 100644
--- a/src/datavisualization/engine/q3dcamera_p.h
+++ b/src/datavisualization/engine/q3dcamera_p.h
@@ -46,6 +46,8 @@ public:
void setRotations(const QPointF &rotation);
+ void updateViewMatrix(qreal zoomAdjustment);
+
public:
Q3DCamera *q_ptr;
@@ -53,11 +55,19 @@ public:
QVector3D m_up;
QMatrix4x4 m_viewMatrix;
+ bool m_isViewMatrixUpdateActive;
GLfloat m_xRotation;
GLfloat m_yRotation;
int m_zoomLevel;
QDataVis::CameraPreset m_activePreset;
+
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class SelectionPointer;
+ friend class Q3DInputHandler;
+ friend class QMac3DInputHandler;
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dlight.cpp b/src/datavisualization/engine/q3dlight.cpp
index 214efa5d..c482e62a 100644
--- a/src/datavisualization/engine/q3dlight.cpp
+++ b/src/datavisualization/engine/q3dlight.cpp
@@ -22,17 +22,36 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+/*!
+ \class Q3DLight
+ \inmodule QtDataVisualization
+ \brief Representation of a light source in 3D space.
+ \since 1.0.0
+
+ Q3DLight represents a monochrome non variable light source in 3D space.
+*/
+
+/*!
+ * Constructs a new 3D light located at origo. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
Q3DLight::Q3DLight(QObject *parent) :
Q3DObject(parent),
d_ptr(new Q3DLightPrivate(this))
{
}
+/*!
+ * Copies the properties of the 3D light from the given source \a source light to this light instance.
+ */
void Q3DLight::copyValuesFrom(const Q3DLight &source)
{
Q3DObject::copyValuesFrom(source);
}
+/*!
+ * Destroys the light object.
+ */
Q3DLight::~Q3DLight()
{
}
@@ -46,10 +65,10 @@ Q3DLightPrivate::~Q3DLightPrivate()
{
}
-// Copies changed values from this light to the other light. If the other light had same changes,
-// those changes are discarded.
void Q3DLightPrivate::sync(Q3DLight &other)
{
+ // Copies changed values from this light to the other light. If the other light had same changes,
+ // those changes are discarded.
if (q_ptr->isDirty()) {
other.copyValuesFrom(*q_ptr);
q_ptr->setDirty(false);
diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp
index ac110d82..55583b5b 100644
--- a/src/datavisualization/engine/q3dobject.cpp
+++ b/src/datavisualization/engine/q3dobject.cpp
@@ -18,19 +18,40 @@
#include "q3dobject.h"
#include "q3dobject_p.h"
+#include "q3dscene.h"
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+/*!
+ \class Q3DObject
+ \inmodule QtDataVisualization
+ \brief Simple baseclass for all the objects in the 3D scene.
+ \since 1.0.0
+
+ Q3DObject is a baseclass that contains only position information for an object in 3D scene.
+ The object is considered to be a single point in the coordinate space without dimensions.
+*/
+
+/*!
+ * Constructs a new 3D object with position set to origo by default. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
Q3DObject::Q3DObject(QObject *parent) :
QObject(parent),
d_ptr(new Q3DObjectPrivate(this))
{
}
+/*!
+ * Destroys the 3D object.
+ */
Q3DObject::~Q3DObject()
{
}
+/*!
+ * Copies the 3D object position from the given \a source 3D object to this 3D object instance.
+ */
void Q3DObject::copyValuesFrom(const Q3DObject &source)
{
d_ptr->m_position.setX(source.d_ptr->m_position.x());
@@ -39,17 +60,25 @@ void Q3DObject::copyValuesFrom(const Q3DObject &source)
setDirty(true);
}
-void Q3DObject::setParentScene(Q3DScene *parentScene)
+/*!
+ * \property Q3DObject::parentScene
+ *
+ * This property contains the parent scene as read only value.
+ * If the object has no parent scene the value is 0.
+ */
+Q3DScene *Q3DObject::parentScene()
{
- if (d_ptr->m_parentScene != parentScene) {
- d_ptr->m_parentScene = parentScene;
- setDirty(true);
- }
+ return qobject_cast<Q3DScene *>(parent());
}
-Q3DScene *Q3DObject::parentScene()
+/*!
+ * \property Q3DObject::position
+ *
+ * This property contains the 3D position of the object.
+ */
+QVector3D Q3DObject::position() const
{
- return d_ptr->m_parentScene;
+ return d_ptr->m_position;
}
void Q3DObject::setPosition(const QVector3D &position)
@@ -60,13 +89,9 @@ void Q3DObject::setPosition(const QVector3D &position)
}
}
-QVector3D Q3DObject::position() const
-{
- return d_ptr->m_position;
-}
-
/*!
- * \internal
+ * Sets and clears the \a dirty flag that is used to track
+ * when the 3D object has changed since last update.
*/
void Q3DObject::setDirty(bool dirty)
{
@@ -74,7 +99,7 @@ void Q3DObject::setDirty(bool dirty)
}
/*!
- * \internal
+ * \return flag that indicates if the 3D object has changed.
*/
bool Q3DObject::isDirty() const
{
@@ -83,7 +108,6 @@ bool Q3DObject::isDirty() const
Q3DObjectPrivate::Q3DObjectPrivate(Q3DObject *q) :
q_ptr(q),
- m_parentScene(0),
m_isDirty(true)
{
}
diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h
index 0b234891..db8ec68b 100644
--- a/src/datavisualization/engine/q3dobject.h
+++ b/src/datavisualization/engine/q3dobject.h
@@ -31,6 +31,8 @@ class Q3DObjectPrivate;
class Q3DObject : public QObject
{
Q_OBJECT
+ Q_PROPERTY(Q3DScene* parentScene READ parentScene)
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition)
public:
Q3DObject(QObject *parent = 0);
@@ -38,11 +40,10 @@ public:
void copyValuesFrom(const Q3DObject &source);
- virtual void setParentScene(Q3DScene *parentScene);
virtual Q3DScene *parentScene();
- virtual void setPosition(const QVector3D &position);
virtual QVector3D position() const;
+ virtual void setPosition(const QVector3D &position);
protected:
void setDirty(bool dirty);
diff --git a/src/datavisualization/engine/q3dobject_p.h b/src/datavisualization/engine/q3dobject_p.h
index 7348c2e8..bac18cfe 100644
--- a/src/datavisualization/engine/q3dobject_p.h
+++ b/src/datavisualization/engine/q3dobject_p.h
@@ -44,7 +44,6 @@ public:
public:
Q3DObject *q_ptr;
- Q3DScene *m_parentScene;
QVector3D m_position;
bool m_isDirty;
};
diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp
index 29eb54f4..2ad15a03 100644
--- a/src/datavisualization/engine/q3dscene.cpp
+++ b/src/datavisualization/engine/q3dscene.cpp
@@ -26,19 +26,48 @@
#include "q3dlight_p.h"
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-
+/*!
+ * \class Q3DScene
+ * \inmodule QtDataVisualization
+ * \brief Q3DScene class provides description of the 3D scene being visualized.
+ * \since 1.0.0
+ *
+ * The 3D scene contains a single active camera and a single active light source.
+ * Visualized data is assumed to be at a fixed location.
+ *
+ * The 3D scene also keeps track of the viewport in which visualization rendering is done,
+ * the primary subviewport inside the viewport where the main 3D data visualization view resides
+ * and the secondary subviewport where the 2D sliced view of the data resides.
+ *
+ * Also the scene has flag for tracking if the secondary 2D slicing view is currently active or not.
+ * \note Not all visualizations support the secondary 2D slicing view.
+ */
+
+/*!
+ * Constructs a basic scene with one light and one camera in it. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
Q3DScene::Q3DScene(QObject *parent) :
QObject(parent),
d_ptr(new Q3DScenePrivate(this))
{
- setCamera(new Q3DCamera(0));
- setLight(new Q3DLight(0));
+ setActiveCamera(new Q3DCamera(0));
+ setActiveLight(new Q3DLight(0));
}
+/*!
+ * Destroys the 3D scene and all the objects contained within it.
+ */
Q3DScene::~Q3DScene()
{
}
+/*!
+ * \property Q3DScene::viewport
+ *
+ * This property contains the current viewport rectangle where all 3D rendering
+ * is targeted.
+ */
QRect Q3DScene::viewport() const
{
return d_ptr->m_viewport;
@@ -55,6 +84,9 @@ void Q3DScene::setViewport(const QRect &viewport)
}
}
+/*!
+ * Sets the \a width and \a height of the viewport only, without changing its location.
+ */
void Q3DScene::setViewportSize(int width, int height)
{
if (d_ptr->m_viewport.width() != width || d_ptr->m_viewport.height() != height) {
@@ -64,96 +96,162 @@ void Q3DScene::setViewportSize(int width, int height)
}
}
-QRect Q3DScene::mainViewport() const
+/*!
+ * \property Q3DScene::primarySubViewport
+ *
+ * This property contains the current main viewport rectangle inside the viewport where the
+ * primary view of the data visualization is targeted to.
+ */
+QRect Q3DScene::primarySubViewport() const
{
- return d_ptr->m_mainViewport;
+ return d_ptr->m_primarySubViewport;
}
-void Q3DScene::setMainViewport(const QRect &mainViewPort)
+void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport)
{
- if (d_ptr->m_mainViewport != mainViewPort) {
- d_ptr->m_mainViewport = mainViewPort;
- d_ptr->m_changeTracker.mainViewportChanged = true;
+ if (d_ptr->m_primarySubViewport != primarySubViewport) {
+ d_ptr->m_primarySubViewport = primarySubViewport;
+ d_ptr->m_changeTracker.primarySubViewportChanged = true;
}
}
-bool Q3DScene::isInputInsideMainView(const QPoint &point)
+/*!
+ * Returns whether the given \a point resides inside the primary subview or not.
+ * The method takes care of correctly mapping between OpenGL coordinates used in the
+ * viewport definitions and the Qt event coordinate system used in the input system.
+ * \return true if the point is inside the primary subview.
+ */
+bool Q3DScene::isPointInPrimarySubView(const QPoint &point)
{
+ // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently.
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());
+ int areaMinX = d_ptr->m_primarySubViewport.x();
+ int areaMaxX = d_ptr->m_primarySubViewport.x() + d_ptr->m_primarySubViewport.width();
+ int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_primarySubViewport.y();
+ int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_primarySubViewport.y() + d_ptr->m_primarySubViewport.height());
return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
}
-bool Q3DScene::isInputInsideSliceView(const QPoint &point)
+/*!
+ * Returns whether the given \a point resides inside the secondary subview or not.
+ * The method takes care of correctly mapping between OpenGL coordinates used in the
+ * viewport definitions and the Qt event coordinate system used in the input system.
+ * \return true if the point is inside the secondary subview.
+ */
+bool Q3DScene::isPointInSecondarySubView(const QPoint &point)
{
+ // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently.
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());
+ int areaMinX = d_ptr->m_secondarySubViewport.x();
+ int areaMaxX = d_ptr->m_secondarySubViewport.x() + d_ptr->m_secondarySubViewport.width();
+ int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_secondarySubViewport.y();
+ int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_secondarySubViewport.y() + d_ptr->m_secondarySubViewport.height());
return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
}
-QRect Q3DScene::sliceViewport() const
+/*!
+ * \property Q3DScene::secondarySubViewport
+ *
+ * This property contains the secondary viewport rectangle inside the viewport. The secondary
+ * viewport is used for drawing the 2D slice view in some visualizations.
+ */
+QRect Q3DScene::secondarySubViewport() const
{
- return d_ptr->m_sliceViewport;
+ return d_ptr->m_secondarySubViewport;
}
-void Q3DScene::setSliceViewport(const QRect &sliceViewPort)
+void Q3DScene::setSecondarySubViewport(const QRect &secondarySubViewport)
{
- if (d_ptr->m_sliceViewport != sliceViewPort) {
- d_ptr->m_sliceViewport = sliceViewPort;
- d_ptr->m_changeTracker.sliceViewportChanged = true;
+ if (d_ptr->m_secondarySubViewport != secondarySubViewport) {
+ d_ptr->m_secondarySubViewport = secondarySubViewport;
+ d_ptr->m_changeTracker.secondarySubViewportChanged = true;
}
}
-// 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.
+/*!
+ * \property Q3DScene::slicingActive
+ *
+ * This property contains whether 2D slicing view is currently active or not.
+ * \note Not all visualizations support the 2D slicing view.
+ */
+bool Q3DScene::isSlicingActive() const
+{
+ return d_ptr->m_isSlicingActive;
+}
-Q3DCamera *Q3DScene::camera() const
+void Q3DScene::setSlicingActive(bool isSlicing)
+{
+ if (d_ptr->m_isSlicingActive != isSlicing) {
+ d_ptr->m_isSlicingActive = isSlicing;
+ d_ptr->m_changeTracker.slicingActivatedChanged = true;
+ }
+}
+
+/*!
+ * \property Q3DScene::activeCamera
+ *
+ * This property contains the currently active camera in the 3D scene.
+ * When a new Q3DCamera objects is set in the property it gets automatically added as child of the scene.
+ */
+Q3DCamera *Q3DScene::activeCamera() const
{
return d_ptr->m_camera;
}
-void Q3DScene::setCamera(Q3DCamera *camera)
+void Q3DScene::setActiveCamera(Q3DCamera *camera)
{
- if (camera != d_ptr->m_camera) {
- // TODO Do we need to be able to swap cameras? May need similar ownership mechanism like axes
- delete d_ptr->m_camera;
+ // Add new camera as child of the scene
+ if (!children().contains(camera))
+ camera->setParent(this);
+ if (camera != d_ptr->m_camera) {
d_ptr->m_camera = camera;
- d_ptr->m_camera->setParentScene(this);
-
d_ptr->m_changeTracker.cameraChanged = true;
-
}
}
-Q3DLight *Q3DScene::light() const
+/*!
+ * \property Q3DScene::activeLight
+ *
+ * This property contains the currently active light in the 3D scene.
+ * When a new Q3DLight objects is set in the property it gets automatically added as child of the scene.
+ */
+Q3DLight *Q3DScene::activeLight() const
{
return d_ptr->m_light;
}
-void Q3DScene::setLight(Q3DLight *light)
+void Q3DScene::setActiveLight(Q3DLight *light)
{
- if (light != d_ptr->m_light) {
- // TODO Do we need to be able to swap lights? May need similar ownership mechanism like axes
- delete d_ptr->m_light;
+ // Add new light as child of the scene
+ if (!children().contains(light))
+ light->setParent(this);
+ if (light != d_ptr->m_light) {
d_ptr->m_light = light;
- d_ptr->m_light->setParentScene(this);
-
d_ptr->m_changeTracker.lightChanged = true;
}
}
+/*!
+ * Calculates and sets the light position relative to the currently active camera using the given parameters.
+ * \a relativePosition defines the relative 3D offset to the current camera position.
+ * Optional \a fixedRotation fixes the light rotation around the data visualization area to the given value in degrees.
+ * Optional \a distanceModifier modifies the distance of the light from the data visualization.
+ */
+void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition,
+ qreal fixedRotation, qreal distanceModifier)
+{
+ d_ptr->m_light->setPosition(
+ d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition,
+ fixedRotation,
+ distanceModifier));
+}
+
bool Q3DScene::isUnderSideCameraEnabled() const
{
return d_ptr->m_isUnderSideCameraEnabled;
@@ -167,35 +265,13 @@ void Q3DScene::setUnderSideCameraEnabled(bool isEnabled)
}
}
-bool Q3DScene::isSlicingActivated() const
-{
- return d_ptr->m_isSlicingActivated;
-}
-
-void Q3DScene::setSlicingActivated(bool isSlicing)
-{
- if (d_ptr->m_isSlicingActivated != isSlicing) {
- d_ptr->m_isSlicingActivated = isSlicing;
- d_ptr->m_changeTracker.slicingActivatedChanged = true;
- }
-}
-
-void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition,
- qreal fixedRotation, qreal distanceModifier)
-{
- d_ptr->m_light->setPosition(
- d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition,
- fixedRotation,
- distanceModifier));
-}
-
Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) :
q_ptr(q),
m_camera(),
m_light(),
m_isUnderSideCameraEnabled(false),
- m_isSlicingActivated(false)
+ m_isSlicingActive(false)
{
}
@@ -214,15 +290,15 @@ void Q3DScenePrivate::sync(Q3DScenePrivate &other)
m_changeTracker.viewportChanged = false;
other.m_changeTracker.viewportChanged = false;
}
- if (m_changeTracker.mainViewportChanged) {
- other.q_ptr->setMainViewport(q_ptr->mainViewport());
- m_changeTracker.mainViewportChanged = false;
- other.m_changeTracker.mainViewportChanged = false;
+ if (m_changeTracker.primarySubViewportChanged) {
+ other.q_ptr->setPrimarySubViewport(q_ptr->primarySubViewport());
+ m_changeTracker.primarySubViewportChanged = false;
+ other.m_changeTracker.primarySubViewportChanged = false;
}
- if (m_changeTracker.sliceViewportChanged) {
- other.q_ptr->setSliceViewport(q_ptr->sliceViewport());
- m_changeTracker.sliceViewportChanged = false;
- other.m_changeTracker.sliceViewportChanged = false;
+ if (m_changeTracker.secondarySubViewportChanged) {
+ other.q_ptr->setSecondarySubViewport(q_ptr->secondarySubViewport());
+ m_changeTracker.secondarySubViewportChanged = false;
+ other.m_changeTracker.secondarySubViewportChanged = false;
}
if (m_changeTracker.cameraChanged) {
m_camera->setDirty(true);
@@ -244,7 +320,7 @@ void Q3DScenePrivate::sync(Q3DScenePrivate &other)
other.m_changeTracker.underSideCameraEnabledChanged = false;
}
if (m_changeTracker.slicingActivatedChanged) {
- other.q_ptr->setSlicingActivated(q_ptr->isSlicingActivated());
+ other.q_ptr->setSlicingActive(q_ptr->isSlicingActive());
m_changeTracker.slicingActivatedChanged = false;
other.m_changeTracker.slicingActivatedChanged = false;
}
diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h
index 7a2a6e30..483a24b8 100644
--- a/src/datavisualization/engine/q3dscene.h
+++ b/src/datavisualization/engine/q3dscene.h
@@ -21,6 +21,7 @@
#include <QtDataVisualization/qdatavisualizationenums.h>
#include <QObject>
+#include <QRect>
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
@@ -32,6 +33,12 @@ class Q3DScenePrivate;
class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QRect viewport READ viewport WRITE setViewport)
+ Q_PROPERTY(QRect primarySubViewport READ primarySubViewport WRITE setPrimarySubViewport)
+ Q_PROPERTY(QRect secondarySubViewport READ secondarySubViewport WRITE setSecondarySubViewport)
+ Q_PROPERTY(bool slicingActive READ isSlicingActive WRITE setSlicingActive)
+ Q_PROPERTY(Q3DCamera* activeCamera READ activeCamera WRITE setActiveCamera)
+ Q_PROPERTY(Q3DLight* activeLight READ activeLight WRITE setActiveLight)
public:
Q3DScene(QObject *parent = 0);
@@ -41,38 +48,41 @@ public:
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 primarySubViewport() const;
+ void setPrimarySubViewport(const QRect &primarySubViewport);
+ bool isPointInPrimarySubView(const QPoint &point);
- QRect sliceViewport() const;
- void setSliceViewport(const QRect &sliceViewport);
- bool isInputInsideSliceView(const QPoint &point);
+ QRect secondarySubViewport() const;
+ void setSecondarySubViewport(const QRect &secondarySubViewport);
+ bool isPointInSecondarySubView(const QPoint &point);
- Q3DCamera *camera() const;
- void setCamera(Q3DCamera *camera);
+ void setSlicingActive(bool isSlicing);
+ bool isSlicingActive() const;
- Q3DLight *light() const;
- void setLight(Q3DLight *light);
+ Q3DCamera *activeCamera() const;
+ void setActiveCamera(Q3DCamera *camera);
- bool isUnderSideCameraEnabled() const;
- void setUnderSideCameraEnabled(bool isEnabled);
-
- void setSlicingActivated(bool isSlicing);
- bool isSlicingActivated() const;
+ Q3DLight *activeLight() const;
+ void setActiveLight(Q3DLight *light);
- // Calcluate light position based on rotation.
- // Call after calling calculateViewMatrix to get up-to-date position
void setLightPositionRelativeToCamera(const QVector3D &relativePosition,
qreal fixedRotation = 0.0,
qreal distanceModifier = 0.0);
private:
+ bool isUnderSideCameraEnabled() const;
+ void setUnderSideCameraEnabled(bool isEnabled);
+
QScopedPointer<Q3DScenePrivate> d_ptr;
Q_DISABLE_COPY(Q3DScene)
+ friend class Q3DScenePrivate;
friend class Abstract3DRenderer;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class Q3DCameraPrivate;
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h
index 29c7bdc4..63d34e97 100644
--- a/src/datavisualization/engine/q3dscene_p.h
+++ b/src/datavisualization/engine/q3dscene_p.h
@@ -40,8 +40,8 @@ class Q3DScene;
struct Q3DSceneChangeBitField {
bool viewportChanged : 1;
- bool mainViewportChanged : 1;
- bool sliceViewportChanged : 1;
+ bool primarySubViewportChanged : 1;
+ bool secondarySubViewportChanged : 1;
bool cameraChanged : 1;
bool lightChanged : 1;
bool underSideCameraEnabledChanged : 1;
@@ -49,8 +49,8 @@ struct Q3DSceneChangeBitField {
Q3DSceneChangeBitField()
: viewportChanged(true),
- mainViewportChanged(true),
- sliceViewportChanged(true),
+ primarySubViewportChanged(true),
+ secondarySubViewportChanged(true),
cameraChanged(true),
lightChanged(true),
underSideCameraEnabledChanged(true),
@@ -71,12 +71,12 @@ public:
Q3DSceneChangeBitField m_changeTracker;
QRect m_viewport;
- QRect m_mainViewport;
- QRect m_sliceViewport;
+ QRect m_primarySubViewport;
+ QRect m_secondarySubViewport;
Q3DCamera *m_camera;
Q3DLight *m_light;
bool m_isUnderSideCameraEnabled;
- bool m_isSlicingActivated;
+ bool m_isSlicingActive;
};
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index eac165d7..3d385c02 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -19,6 +19,7 @@
#include "scatter3drenderer_p.h"
#include "scatter3dcontroller_p.h"
#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "texturehelper_p.h"
@@ -164,19 +165,19 @@ void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy)
void Scatter3DRenderer::updateScene(Q3DScene *scene)
{
// TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
- scene->setMainViewport(m_mainViewPort);
+ scene->setPrimarySubViewport(m_mainViewPort);
scene->setUnderSideCameraEnabled(true);
if (m_hasHeightAdjustmentChanged) {
- // 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));
+ // Set initial m_cachedScene->activeCamera() position. Also update if height adjustment has changed.
+ scene->activeCamera()->setBaseOrientation(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->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
+ // Set light position (rotate light with m_cachedScene->activeCamera(), a bit above it (as set in defaultLightPos))
scene->setLightPositionRelativeToCamera(defaultLightPos);
Abstract3DRenderer::updateScene(scene);
@@ -205,7 +206,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
/ (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
// Calculate view matrix
- QMatrix4x4 viewMatrix = m_cachedScene->camera()->viewMatrix();
+ QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix();
// Calculate label flipping
if (viewMatrix.row(0).x() > 0)
@@ -234,7 +235,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
backgroundRotation = 0.0f;
// Get light position from the scene
- QVector3D lightPos = m_cachedScene->light()->position();
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
// Map adjustment direction to model matrix scaling
// TODO: Let's use these for testing the autoscaling of dots based on their number
@@ -269,7 +270,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Get the depth view matrix
// It may be possible to hack lightPos here if we want to make some tweaks to shadow
- QVector3D depthLightPos = m_cachedScene->camera()->calculatePositionRelativeToCamera(
+ QVector3D depthLightPos = m_cachedScene->activeCamera()->calculatePositionRelativeToCamera(
defaultLightPos, 0.0f, 1.0f / m_autoScaleAdjustment);
depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, 0.0f, zComp),
QVector3D(0.0f, 1.0f, 0.0f));
@@ -1131,7 +1132,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
@@ -1191,7 +1192,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
@@ -1244,7 +1245,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
// Side wall
@@ -1266,7 +1267,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, m_cachedScene->camera(), true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
@@ -1334,7 +1335,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QVector3D(0.0f, 0.0f, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, m_cachedScene->camera(), true, false, Drawer::LabelMid);
+ m_labelObj, m_cachedScene->activeCamera(), true, false, Drawer::LabelMid);
// Reset label update flag; they should have been updated when we get here
m_updateLabels = false;
diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp
index 98a75f86..ae0cf1d3 100644
--- a/src/datavisualization/engine/selectionpointer.cpp
+++ b/src/datavisualization/engine/selectionpointer.cpp
@@ -22,6 +22,7 @@
#include "objecthelper_p.h"
#include "texturehelper_p.h"
#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "drawer_p.h"
#include "utils_p.h"
#include "q3dlight.h"
@@ -91,7 +92,7 @@ void SelectionPointer::render(GLuint defaultFboHandle)
{
Q_UNUSED(defaultFboHandle)
- Q3DCamera *camera = m_cachedScene->camera();
+ Q3DCamera *camera = m_cachedScene->activeCamera();
QSize textureSize = m_labelItem.size();
QMatrix4x4 itModelMatrix;
@@ -124,7 +125,7 @@ void SelectionPointer::render(GLuint defaultFboHandle)
// Enable texturing
glEnable(GL_TEXTURE_2D);
- QVector3D lightPos = m_cachedScene->light()->position();
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
//
// Draw the point
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 3505d304..e477fca3 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -19,6 +19,7 @@
#include "surface3dcontroller_p.h"
#include "surface3drenderer_p.h"
#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "surfaceobject_p.h"
@@ -254,20 +255,20 @@ QRect Surface3DRenderer::calculateSampleRect(QSurfaceDataProxy *dataProxy)
void Surface3DRenderer::updateScene(Q3DScene *scene)
{
// TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
- scene->setMainViewport(m_mainViewPort);
+ scene->setPrimarySubViewport(m_mainViewPort);
scene->setUnderSideCameraEnabled(m_hasNegativeValues);
// Set initial camera position
// X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
if (m_hasHeightAdjustmentChanged) {
- scene->camera()->setDefaultOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
+ scene->activeCamera()->setBaseOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
// For now this is used just to make things once. Proper use will come
m_hasHeightAdjustmentChanged = false;
}
- scene->camera()->updateViewMatrix(m_autoScaleAdjustment);
+ scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
scene->setLightPositionRelativeToCamera(defaultLightPos);
if (m_selectionPointer)
@@ -292,7 +293,7 @@ void Surface3DRenderer::render(GLuint defaultFboHandle)
void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
{
- Q3DCamera *camera = m_cachedScene->camera();
+ Q3DCamera *camera = m_cachedScene->activeCamera();
GLfloat backgroundRotation = 0;
// Specify viewport
@@ -305,7 +306,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
/ (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
// Calculate view matrix
- QMatrix4x4 viewMatrix = m_cachedScene->camera()->viewMatrix();
+ QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix();
// Calculate flipping indicators
if (viewMatrix.row(0).x() > 0)
@@ -328,7 +329,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
backgroundRotation = 0.0f;
// TODO: add 0.0f, 1.0f / m_autoScaleAdjustment
- QVector3D lightPos = m_cachedScene->light()->position();
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
QMatrix4x4 depthViewMatrix;
QMatrix4x4 depthProjectionMatrix;
@@ -598,25 +599,25 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// 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)
+#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowNone) {
// Set shadow shader bindings
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(m_shader, m_gridLineObj, 0, m_depthTexture);
} else
- #endif
+#endif
{
// Set shadowless shader bindings
lineShader->setUniformValue(lineShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ m_cachedTheme.m_lightStrength);
// Draw the object
m_drawer->drawObject(m_shader, m_gridLineObj);
@@ -648,25 +649,25 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// 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)
+#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowNone) {
// Set shadow shader bindings
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(m_shader, m_gridLineObj, 0, m_depthTexture);
} else
- #endif
+#endif
{
// Set shadowless shader bindings
lineShader->setUniformValue(lineShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ m_cachedTheme.m_lightStrength);
// Draw the object
m_drawer->drawObject(m_shader, m_gridLineObj);
@@ -702,25 +703,25 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// 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)
+#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowNone) {
// Set shadow shader bindings
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(m_shader, m_gridLineObj, 0, m_depthTexture);
} else
- #endif
+#endif
{
// Set shadowless shader bindings
lineShader->setUniformValue(lineShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ m_cachedTheme.m_lightStrength);
// Draw the object
m_drawer->drawObject(m_shader, m_gridLineObj);
@@ -753,25 +754,25 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// 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)
+#if !defined(QT_OPENGL_ES_2)
if (m_cachedShadowQuality > QDataVis::ShadowNone) {
// Set shadow shader bindings
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(m_shader, m_gridLineObj, 0, m_depthTexture);
} else
- #endif
+#endif
{
// Set shadowless shader bindings
lineShader->setUniformValue(lineShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ m_cachedTheme.m_lightStrength);
// Draw the object
m_drawer->drawObject(m_shader, m_gridLineObj);
@@ -970,10 +971,10 @@ void Surface3DRenderer::requestSelectionAtPoint(const QPoint &point)
{
Q_UNUSED(point)
-// QMutexLocker locker(&m_mutex);
-// m_selectionPointRequest.setX(point.x());
-// m_selectionPointRequest.setY(point.y());
-// m_isSelectionPointRequestActive = true;
+ // QMutexLocker locker(&m_mutex);
+ // m_selectionPointRequest.setX(point.x());
+ // m_selectionPointRequest.setY(point.y());
+ // m_isSelectionPointRequestActive = true;
m_querySelection = true;
}
diff --git a/src/datavisualization/input/q3dinputhandler.cpp b/src/datavisualization/input/q3dinputhandler.cpp
index 8c7d83d0..6fd5f08b 100644
--- a/src/datavisualization/input/q3dinputhandler.cpp
+++ b/src/datavisualization/input/q3dinputhandler.cpp
@@ -19,6 +19,7 @@
#include "datavisualizationglobal_p.h"
#include "q3dinputhandler.h"
#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "q3dlight.h"
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
@@ -32,28 +33,46 @@ const int nearZoomRangeDivider = 12;
const int midZoomRangeDivider = 60;
const int farZoomRangeDivider = 120;
-const qreal rotationSpeed = 100.0;
+const float rotationSpeed = 100.0f;
+/*!
+ \class Q3DInputHandler
+ \inmodule QtDataVisualization
+ \brief Basic wheel mouse based input handler.
+ \since 1.0.0
+
+ Q3DInputHandler is the basic input handler for wheel mouse type of input devices.
+*/
+
+/*!
+ * Constructs the basic mouse input handler. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
Q3DInputHandler::Q3DInputHandler(QObject *parent) :
QAbstract3DInputHandler(parent)
{
}
+/*!
+ * Destroys the input handler.
+ */
Q3DInputHandler::~Q3DInputHandler()
{
}
// Input event listeners
+/*!
+ * Override this to change handling of mouse press events.
+ * Mouse press event is given in the \a event and the mouse position in \a mousePos.
+ */
void Q3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
{
if (Qt::LeftButton == event->button()) {
- if (scene()->isSlicingActivated()) {
- if (scene()->isInputInsideMainView(mousePos)) {
+ if (scene()->isSlicingActive()) {
+ if (scene()->isPointInPrimarySubView(mousePos)) {
setInputState(QDataVis::InputOnOverview);
- //qDebug() << "Mouse pressed on overview";
- } else if (scene()->isInputInsideSliceView(mousePos)) {
+ } else if (scene()->isPointInSecondarySubView(mousePos)) {
setInputState(QDataVis::InputOnSlice);
- //qDebug() << "Mouse pressed on zoom";
} else {
setInputState(QDataVis::InputNone);
}
@@ -63,21 +82,23 @@ void Q3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos
setInputPosition(mousePos);
// TODO: Get rid of these (QTRD-2307)
emit selectionAtPoint(mousePos);
- //qDebug() << "Mouse pressed on scene";
-
}
} else if (Qt::MiddleButton == event->button()) {
// reset rotations
setInputPosition(QPoint(0, 0));
} else if (Qt::RightButton == event->button()) {
// disable rotating when in slice view
- if (!scene()->isSlicingActivated())
+ if (!scene()->isSlicingActive())
setInputState(QDataVis::InputRotating);
// update mouse positions to prevent jumping when releasing or repressing a button
setInputPosition(mousePos);
}
}
+/*!
+ * Override this to change handling of mouse release events.
+ * Mouse release event is given in the \a event and the mouse position in \a mousePos.
+ */
void Q3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
{
Q_UNUSED(event);
@@ -88,13 +109,17 @@ void Q3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mouseP
setInputState(QDataVis::InputNone);
}
+/*!
+ * Override this to change handling of mouse move events.
+ * Mouse move event is given in the \a event and the mouse position in \a mousePos.
+ */
void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
{
Q_UNUSED(event);
if (QDataVis::InputRotating == inputState()) {
// Calculate mouse movement since last frame
- QPointF rotations = scene()->camera()->rotations();
+ QPointF rotations = scene()->activeCamera()->rotations();
GLfloat xRotation = rotations.x();
GLfloat yRotation = rotations.y();
GLfloat mouseMoveX = GLfloat(inputPosition().x() - mousePos.x())
@@ -104,22 +129,26 @@ void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
// Apply to rotations
xRotation -= mouseMoveX;
yRotation -= mouseMoveY;
- scene()->camera()->setRotations(QPointF(xRotation, yRotation));
- scene()->camera()->updateViewMatrix(1.0f);
+ scene()->activeCamera()->setRotations(QPointF(xRotation, yRotation));
+ scene()->activeCamera()->d_ptr->updateViewMatrix(1.0f);
setPreviousInputPos(inputPosition());
setInputPosition(mousePos);
}
}
+/*!
+ * Override this to change handling of wheel events.
+ * The wheel event is given in the \a event.
+ */
void Q3DInputHandler::wheelEvent(QWheelEvent *event)
{
// disable zooming if in slice view
- if (scene()->isSlicingActivated())
+ if (scene()->isSlicingActive())
return;
// Adjust zoom level based on what zoom range we're in.
- int zoomLevel = scene()->camera()->zoomLevel();
+ int zoomLevel = scene()->activeCamera()->zoomLevel();
if (zoomLevel > oneToOneZoomLevel)
zoomLevel += event->angleDelta().y() / nearZoomRangeDivider;
else if (zoomLevel > halfSizeZoomLevel)
@@ -131,7 +160,7 @@ void Q3DInputHandler::wheelEvent(QWheelEvent *event)
else if (zoomLevel < minZoomLevel)
zoomLevel = minZoomLevel;
- scene()->camera()->setZoomLevel(zoomLevel);
+ scene()->activeCamera()->setZoomLevel(zoomLevel);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/input/q3dinputhandler.h b/src/datavisualization/input/q3dinputhandler.h
index a337d4d6..4d49d318 100644
--- a/src/datavisualization/input/q3dinputhandler.h
+++ b/src/datavisualization/input/q3dinputhandler.h
@@ -37,9 +37,6 @@ public:
virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
virtual void wheelEvent(QWheelEvent *event);
-signals:
- void rotationSpeedChanged(int rotationSpeed);
-
private:
Q_DISABLE_COPY(Q3DInputHandler)
};
diff --git a/src/datavisualization/input/qabstract3dinputhandler.cpp b/src/datavisualization/input/qabstract3dinputhandler.cpp
index 8b1a3419..9dd5f862 100644
--- a/src/datavisualization/input/qabstract3dinputhandler.cpp
+++ b/src/datavisualization/input/qabstract3dinputhandler.cpp
@@ -19,51 +19,99 @@
QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+/*!
+ \class QAbstract3DInputHandler
+ \inmodule QtDataVisualization
+ \brief Baseclass for implementations of input handlers.
+ \since 1.0.0
+
+ QAbstract3DInputHandler is a baseclass that is subclassed by different input handling implementations
+ that take input events and translate those to camera and light movements. Input handlers also translate
+ raw input events to slicing and selection events in the scene.
+*/
+
+/*!
+ * Constructs the baseclass. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
QAbstract3DInputHandler::QAbstract3DInputHandler(QObject *parent) :
QObject(parent),
d_ptr(new QAbstract3DInputHandlerPrivate(this))
{
}
+/*!
+ * Destroys the baseclass.
+ */
QAbstract3DInputHandler::~QAbstract3DInputHandler()
{
}
// Input event listeners
+/*!
+ * Override this to handle mouse double click events.
+ * Mouse double click event is given in the \a event.
+ */
void QAbstract3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_UNUSED(event);
}
+/*!
+ * Override this to handle touch input events.
+ * Touch event is given in the \a event.
+ */
void QAbstract3DInputHandler::touchEvent(QTouchEvent *event)
{
Q_UNUSED(event);
}
+/*!
+ * Override this to handle mouse press events.
+ * Mouse press event is given in the \a event and the mouse position in \a mousePos.
+ */
void QAbstract3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
{
Q_UNUSED(event);
Q_UNUSED(mousePos);
}
+/*!
+ * Override this to handle mouse release events.
+ * Mouse release event is given in the \a event and the mouse position in \a mousePos.
+ */
void QAbstract3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
{
Q_UNUSED(event);
Q_UNUSED(mousePos);
}
+/*!
+ * Override this to handle mouse move events.
+ * Mouse move event is given in the \a event and the mouse position in \a mousePos.
+ */
void QAbstract3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
{
Q_UNUSED(event);
Q_UNUSED(mousePos);
}
+/*!
+ * Override this to handle wheel events.
+ * Wheel event is given in the \a event.
+ */
void QAbstract3DInputHandler::wheelEvent(QWheelEvent *event)
{
Q_UNUSED(event);
}
// Property get/set
+/*!
+ * \property QAbstract3DInputHandler::inputState
+ *
+ * Current enumerated input state based on the processed input events.
+ * When the state changes inputStateChanged() is emitted.
+ */
QDataVis::InputState QAbstract3DInputHandler::inputState()
{
return d_ptr->m_inputState;
@@ -77,6 +125,11 @@ void QAbstract3DInputHandler::setInputState(QDataVis::InputState inputState)
}
}
+/*!
+ * \property QAbstract3DInputHandler::inputPosition
+ *
+ * Last input position based on the processed input events.
+ */
QPoint QAbstract3DInputHandler::inputPosition() const
{
return d_ptr->m_inputPosition;
@@ -90,17 +143,27 @@ void QAbstract3DInputHandler::setInputPosition(const QPoint &position)
}
}
-void QAbstract3DInputHandler::setPrevDistance(int distance)
-{
- d_ptr->m_prevDistance = distance;
-}
-
+/*!
+ * \return the manhattan length between last two input positions.
+ */
int QAbstract3DInputHandler::prevDistance() const
{
return d_ptr->m_prevDistance;
}
+/*!
+ * Sets the \a distance (manhattan length) between last two input positions.
+ */
+void QAbstract3DInputHandler::setPrevDistance(int distance)
+{
+ d_ptr->m_prevDistance = distance;
+}
+/*!
+ * \property QAbstract3DInputHandler::scene
+ *
+ * The 3D scene this abstract inputhandler is controlling. Only one scene can be controlled by one input handler.
+ */
Q3DScene *QAbstract3DInputHandler::scene() const
{
return d_ptr->m_scene;
@@ -111,18 +174,24 @@ void QAbstract3DInputHandler::setScene(Q3DScene *scene)
d_ptr->m_scene = scene;
}
+/*!
+ * Sets the previous input position to the point given by \a position.
+ */
void QAbstract3DInputHandler::setPreviousInputPos(const QPoint &position)
{
d_ptr->m_previousInputPos = position;
}
+/*!
+ * Returns the previous input position.
+ * \return Previous input position.
+ */
QPoint QAbstract3DInputHandler::previousInputPos() const
{
return d_ptr->m_previousInputPos;
}
-
QAbstract3DInputHandlerPrivate::QAbstract3DInputHandlerPrivate(QAbstract3DInputHandler *q) :
q_ptr(q),
m_prevDistance(0),
diff --git a/src/datavisualization/input/qabstract3dinputhandler.h b/src/datavisualization/input/qabstract3dinputhandler.h
index d19f626d..96d4de97 100644
--- a/src/datavisualization/input/qabstract3dinputhandler.h
+++ b/src/datavisualization/input/qabstract3dinputhandler.h
@@ -32,7 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DInputHandler : public QObject
Q_OBJECT
Q_PROPERTY(QtDataVisualization::QDataVis::InputState inputState READ inputState WRITE setInputState NOTIFY inputStateChanged)
Q_PROPERTY(QPoint inputPosition READ inputPosition WRITE setInputPosition NOTIFY positionChanged)
- Q_PROPERTY(Q3DScene *scene READ scene WRITE setScene)
+ Q_PROPERTY(Q3DScene *scene READ scene WRITE setScene NOTIFY sceneChanged)
public:
explicit QAbstract3DInputHandler(QObject *parent = 0);
@@ -47,28 +47,28 @@ public:
virtual void wheelEvent(QWheelEvent *event);
public:
- // Property get/set functions
-
// TODO: Check if the inputState needs to be visible outside of subclasses in the final architecture
QDataVis::InputState inputState();
void setInputState(QDataVis::InputState inputState);
- void setInputPosition(const QPoint &position);
+
QPoint inputPosition() const;
+ void setInputPosition(const QPoint &position);
Q3DScene *scene() const;
void setScene(Q3DScene *scene);
+signals:
+ void positionChanged(const QPoint &position);
+ void inputStateChanged(QDataVis::InputState state);
+ void selectionAtPoint(const QPoint &point);
+ void sceneChanged(const Q3DScene *scene);
+
protected:
void setPrevDistance(int distance);
int prevDistance() const;
void setPreviousInputPos(const QPoint &position);
QPoint previousInputPos() const;
-signals:
- void positionChanged(const QPoint &position);
- void inputStateChanged(QDataVis::InputState state);
- void selectionAtPoint(const QPoint &point);
-
private:
Q_DISABLE_COPY(QAbstract3DInputHandler)
diff --git a/src/datavisualization/input/qtouch3dinputhandler.cpp b/src/datavisualization/input/qtouch3dinputhandler.cpp
index f77ac9c0..de5ba843 100644
--- a/src/datavisualization/input/qtouch3dinputhandler.cpp
+++ b/src/datavisualization/input/qtouch3dinputhandler.cpp
@@ -25,20 +25,40 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
const qreal maxTapAndHoldJitter = 10;
const int tapAndHoldTime = 250;
+/*!
+ \class QTouch3DInputHandler
+ \inmodule QtDataVisualization
+ \brief Basic touch display based input handler.
+ \since 1.0.0
+
+ QTouch3DInputHandler is the basic input handler for touch screen devices.
+*/
+
+/*!
+ * Constructs the basic touch display input handler. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
QTouch3DInputHandler::QTouch3DInputHandler(QObject *parent)
: Q3DInputHandler(parent),
d_ptr(new QTouch3DInputHandlerPrivate(this))
{
}
+/*!
+ * Destroys the input handler.
+ */
QTouch3DInputHandler::~QTouch3DInputHandler()
{
}
// Input event listeners
+/*!
+ * Override this to change handling of mouse double click events.
+ * Mouse double click event is given in the \a event.
+ */
void QTouch3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event)
{
- if (!scene()->isSlicingActivated()) {
+ if (!scene()->isSlicingActive()) {
setInputState(QDataVis::InputOnScene);
// update mouse positions to prevent jumping when releasing or repressing a button
setInputPosition(event->pos());
@@ -47,12 +67,16 @@ void QTouch3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event)
}
}
+/*!
+ * Override this to change handling of touch events.
+ * Touch event is given in the \a event.
+ */
void QTouch3DInputHandler::touchEvent(QTouchEvent *event)
{
QList<QTouchEvent::TouchPoint> points;
points = event->touchPoints();
- if (!scene()->isSlicingActivated() && points.count() == 2) {
+ if (!scene()->isSlicingActive() && points.count() == 2) {
d_ptr->m_holdTimer->stop();
setInputState(QDataVis::InputOnPinch);
@@ -60,7 +84,7 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event)
QPointF distance = points.at(0).pos() - points.at(1).pos();
int newDistance = distance.manhattanLength();
int zoomRate = 1;
- int zoomLevel = scene()->camera()->zoomLevel();
+ int zoomLevel = scene()->activeCamera()->zoomLevel();
if (zoomLevel > 100)
zoomRate = 5;
if (newDistance > prevDistance())
@@ -71,9 +95,9 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event)
zoomLevel = 500;
else if (zoomLevel < 10)
zoomLevel = 10;
- scene()->camera()->setZoomLevel(zoomLevel);
+ scene()->activeCamera()->setZoomLevel(zoomLevel);
setPrevDistance(newDistance);
- } else if (!scene()->isSlicingActivated() && points.count() == 1) {
+ } else if (!scene()->isSlicingActive() && points.count() == 1) {
if (event->type() == QEvent::TouchBegin) {
// Tap-and-hold selection start
d_ptr->m_startHoldPos = points.at(0).pos();
@@ -89,15 +113,20 @@ void QTouch3DInputHandler::touchEvent(QTouchEvent *event)
}
}
+/*!
+ * Override this to change handling of mouse press events.
+ * Mouse press event is given in the \a event and the mouse position in \a mousePos.
+ * \warning This method is subject to change or removal.
+ */
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.
if (Qt::LeftButton == event->button()) {
- if (scene()->isSlicingActivated()) {
- if (scene()->isInputInsideMainView(mousePos)) {
+ if (scene()->isSlicingActive()) {
+ if (scene()->isPointInPrimarySubView(mousePos)) {
setInputState(QDataVis::InputOnOverview);
//qDebug() << "Mouse pressed on overview";
- } else if (scene()->isInputInsideSliceView(mousePos)) {
+ } else if (scene()->isPointInSecondarySubView(mousePos)) {
setInputState(QDataVis::InputOnSlice);
//qDebug() << "Mouse pressed on zoom";
} else {
diff --git a/src/datavisualization/input/qtouch3dinputhandler.h b/src/datavisualization/input/qtouch3dinputhandler.h
index 2c4b67dd..d33807a6 100644
--- a/src/datavisualization/input/qtouch3dinputhandler.h
+++ b/src/datavisualization/input/qtouch3dinputhandler.h
@@ -20,6 +20,7 @@
#define QTOUCH3DINPUTHANDLER_H
#include <QtDataVisualization/q3dinputhandler.h>
+#include "q3dcamera.h"
QT_DATAVISUALIZATION_BEGIN_NAMESPACE