diff options
author | Keränen Pasi <pasi.keranen@digia.com> | 2013-09-13 11:13:16 +0300 |
---|---|---|
committer | Pasi Keränen <pasi.keranen@digia.com> | 2013-09-19 12:11:33 +0300 |
commit | 802681d854d93a50547585570da3bcf7b6c41636 (patch) | |
tree | 2818f239df688f6ad5b91b2ac9d638ffae34e24a /src | |
parent | 35a5a5302fdcf43bc571f51f03512e3df9d2c58c (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')
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 |