diff options
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer.cpp | 22 | ||||
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer_p.h | 1 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dsurface.cpp | 21 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dsurface.h | 4 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 1 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3dcontroller.cpp | 23 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3dcontroller_p.h | 15 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer.cpp | 41 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer_p.h | 2 |
9 files changed, 107 insertions, 23 deletions
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 56a5ba60..f7cb5499 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -61,6 +61,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_xFlipped(false), m_yFlipped(false), m_zFlipped(false), + m_yFlippedForGrid(false), m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), @@ -665,7 +666,7 @@ void Abstract3DRenderer::drawAxisTitleX(const QVector3D &labelRotation, float offsetRotation = labelRotation.z(); float extraRotation = -90.0f; Qt::AlignmentFlag alignment = Qt::AlignTop; - if (m_yFlipped) { + if (m_yFlippedForGrid) { alignment = Qt::AlignBottom; zRotation = 180.0f; if (m_zFlipped) { @@ -745,7 +746,7 @@ void Abstract3DRenderer::drawAxisTitleZ(const QVector3D &labelRotation, float xRotation = -90.0f; float extraRotation = 90.0f; Qt::AlignmentFlag alignment = Qt::AlignTop; - if (m_yFlipped) { + if (m_yFlippedForGrid) { alignment = Qt::AlignBottom; xRotation = -xRotation; if (m_zFlipped) { @@ -1185,6 +1186,10 @@ void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePo const QVector<float> &subGridPositions = m_axisCacheZ.formatter()->subGridPositions(); int mainSize = gridPositions.size(); QVector3D translateVector(0.0f, yFloorLinePos, 0.0f); + QQuaternion finalRotation = m_xRightAngleRotationNeg; + if (m_yFlippedForGrid) + finalRotation *= m_xFlipRotation; + for (int i = 0; i < gridLineCount; i++) { float gridPosition = (i >= mainSize) ? subGridPositions.at(i - mainSize) : gridPositions.at(i); @@ -1200,8 +1205,8 @@ void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePo modelMatrix.translate(translateVector); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); - modelMatrix.rotate(m_xRightAngleRotationNeg); - itModelMatrix.rotate(m_xRightAngleRotationNeg); + modelMatrix.rotate(finalRotation); + itModelMatrix.rotate(finalRotation); QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; shader->setUniformValue(shader->model(), modelMatrix); @@ -1229,13 +1234,16 @@ void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLineP const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix) { - float halfRatio(m_graphAspectRatio / 2.0f); + float halfRatio((m_graphAspectRatio + (labelMargin / 2.0f)) / 2.0f); QVector3D gridLineScaler(gridLineWidth, gridLineWidth, halfRatio); int gridLineCount = m_axisCacheX.gridLineCount(); const QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions(); const QVector<float> &subGridPositions = m_axisCacheX.formatter()->subGridPositions(); int mainSize = gridPositions.size(); QVector3D translateVector(0.0f, yFloorLinePos, -halfRatio); + QQuaternion finalRotation = m_xRightAngleRotationNeg; + if (m_yFlippedForGrid) + finalRotation *= m_xFlipRotation; for (int i = 0; i < gridLineCount; i++) { QMatrix4x4 modelMatrix; QMatrix4x4 itModelMatrix; @@ -1247,8 +1255,8 @@ void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLineP modelMatrix.translate(translateVector); modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); - modelMatrix.rotate(m_xRightAngleRotationNeg); - itModelMatrix.rotate(m_xRightAngleRotationNeg); + modelMatrix.rotate(finalRotation); + itModelMatrix.rotate(finalRotation); QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; shader->setUniformValue(shader->model(), modelMatrix); diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 33337441..10e88f3f 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -246,6 +246,7 @@ protected: bool m_xFlipped; bool m_yFlipped; bool m_zFlipped; + bool m_yFlippedForGrid; ObjectHelper *m_backgroundObj; // Shared reference ObjectHelper *m_gridLineObj; // Shared reference diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index c5ce29d7..c9af656f 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -98,6 +98,8 @@ Q3DSurface::Q3DSurface(const QSurfaceFormat *format, QWindow *parent) dptr()->m_shared->initializeOpenGL(); QObject::connect(dptr()->m_shared, &Surface3DController::selectedSeriesChanged, this, &Q3DSurface::selectedSeriesChanged); + QObject::connect(dptr()->m_shared, &Surface3DController::flipHorizontalGridChanged, + this, &Q3DSurface::flipHorizontalGridChanged); } /*! @@ -230,6 +232,25 @@ QSurface3DSeries *Q3DSurface::selectedSeries() const } /*! + * \property Q3DSurface::flipHorizontalGrid + * + * If \c{false}, the horizontal axis grid and labels are drawn on the horizontal background + * of the graph. + * If \c{true}, the horizontal axis grid and labels are drawn on the opposite side of the graph + * from the horizontal background. + * Defaults to \c{false}. + */ +void Q3DSurface::setFlipHorizontalGrid(bool flip) +{ + dptr()->m_shared->setFlipHorizontalGrid(flip); +} + +bool Q3DSurface::flipHorizontalGrid() const +{ + return dptrc()->m_shared->flipHorizontalGrid(); +} + +/*! * Adds \a axis to the graph. The axes added via addAxis are not yet taken to use, * addAxis is simply used to give the ownership of the \a axis to the graph. * The \a axis must not be null or added to another graph. diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index 9868c844..86740519 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public QAbstract3DGraph Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged) Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged) Q_PROPERTY(QSurface3DSeries *selectedSeries READ selectedSeries NOTIFY selectedSeriesChanged) + Q_PROPERTY(bool flipHorizontalGrid READ flipHorizontalGrid WRITE setFlipHorizontalGrid NOTIFY flipHorizontalGridChanged) public: explicit Q3DSurface(const QSurfaceFormat *format = 0, QWindow *parent = 0); @@ -55,12 +56,15 @@ public: QList<QValue3DAxis *> axes() const; QSurface3DSeries *selectedSeries() const; + void setFlipHorizontalGrid(bool flip); + bool flipHorizontalGrid() const; signals: void axisXChanged(QValue3DAxis *axis); void axisYChanged(QValue3DAxis *axis); void axisZChanged(QValue3DAxis *axis); void selectedSeriesChanged(QSurface3DSeries *series); + void flipHorizontalGridChanged(bool flip); private: Q3DSurfacePrivate *dptr(); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index f6b044f6..944d9c9b 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -372,6 +372,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) m_yFlipped = true; else m_yFlipped = false; + m_yFlippedForGrid = m_yFlipped; // Polar axis grid drawing in abstract needs this // Calculate background rotation if (!m_zFlipped && !m_xFlipped) diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index c03bafd8..5293cb0c 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -29,7 +29,8 @@ Surface3DController::Surface3DController(QRect rect, Q3DScene *scene) m_renderer(0), m_selectedPoint(invalidSelectionPosition()), m_selectedSeries(0), - m_flatShadingSupported(true) + m_flatShadingSupported(true), + m_flipHorizontalGrid(false) { // Setting a null axis creates a new default axis according to orientation and graph type. // Note: these cannot be set in the Abstract3DController constructor, as they will call virtual @@ -79,6 +80,11 @@ void Surface3DController::synchDataToRenderer() m_renderer->updateSelectedPoint(m_selectedPoint, m_selectedSeries); m_changeTracker.selectedPointChanged = false; } + + if (m_changeTracker.flipHorizontalGridChanged) { + m_renderer->updateFlipHorizontalGrid(m_flipHorizontalGrid); + m_changeTracker.flipHorizontalGridChanged = false; + } } void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation( @@ -168,6 +174,21 @@ QList<QSurface3DSeries *> Surface3DController::surfaceSeriesList() return surfaceSeriesList; } +void Surface3DController::setFlipHorizontalGrid(bool flip) +{ + if (m_flipHorizontalGrid != flip) { + m_flipHorizontalGrid = flip; + m_changeTracker.flipHorizontalGridChanged = true; + emit flipHorizontalGridChanged(flip); + emitNeedRender(); + } +} + +bool Surface3DController::flipHorizontalGrid() const +{ + return m_flipHorizontalGrid; +} + void Surface3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { // Currently surface only supports row and column modes when also slicing diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h index 2be74f35..653f41c3 100644 --- a/src/datavisualization/engine/surface3dcontroller_p.h +++ b/src/datavisualization/engine/surface3dcontroller_p.h @@ -38,14 +38,16 @@ class Surface3DRenderer; class QSurface3DSeries; struct Surface3DChangeBitField { - bool selectedPointChanged : 1; - bool rowsChanged : 1; - bool itemChanged : 1; + bool selectedPointChanged : 1; + bool rowsChanged : 1; + bool itemChanged : 1; + bool flipHorizontalGridChanged : 1; Surface3DChangeBitField() : selectedPointChanged(true), rowsChanged(false), - itemChanged(false) + itemChanged(false), + flipHorizontalGridChanged(true) { } }; @@ -73,6 +75,7 @@ private: bool m_flatShadingSupported; QVector<ChangeItem> m_changedItems; QVector<ChangeRow> m_changedRows; + bool m_flipHorizontalGrid; public: explicit Surface3DController(QRect rect, Q3DScene *scene = 0); @@ -101,6 +104,9 @@ public: virtual void removeSeries(QAbstract3DSeries *series); virtual QList<QSurface3DSeries *> surfaceSeriesList(); + void setFlipHorizontalGrid(bool flip); + bool flipHorizontalGrid() const; + public slots: void handleArrayReset(); void handleRowsAdded(int startIndex, int count); @@ -113,6 +119,7 @@ public slots: signals: void selectedSeriesChanged(QSurface3DSeries *series); + void flipHorizontalGridChanged(bool flip); private: Q_DISABLE_COPY(Surface3DController) diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 60e501f1..5fd59e5e 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -1050,6 +1050,17 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) else m_xFlipped = true; + if (m_flipHorizontalGrid) { + // Need to determine if camera is below graph top + float distanceToCenter = activeCamera->position().length() + / activeCamera->zoomLevel() / m_autoScaleAdjustment * 100.0f; + qreal cameraAngle = qreal(activeCamera->yRotation()) / 180.0 * M_PI; + float cameraYPos = float(qSin(cameraAngle)) * distanceToCenter; + m_yFlippedForGrid = cameraYPos < backgroundMargin; + } else { + m_yFlippedForGrid = m_yFlipped; + } + // calculate background rotation based on view matrix rotation if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0) backgroundRotation = 270.0f; @@ -1467,13 +1478,13 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) else lineYRotation = m_yRightAngleRotation; - if (m_yFlipped) + if (m_yFlippedForGrid) lineXRotation = m_xRightAngleRotation; else lineXRotation = m_xRightAngleRotationNeg; float yFloorLinePosition = -backgroundMargin + gridLineOffset; - if (m_yFlipped) + if (m_yFlipped != m_flipHorizontalGrid) yFloorLinePosition = -yFloorLinePosition; // Rows (= Z) @@ -1844,7 +1855,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa if (m_axisCacheZ.segmentCount() > 0) { int labelCount = m_axisCacheZ.labelCount(); float labelXTrans = 0.0f; - float labelYTrans = -backgroundMargin; + float labelYTrans = m_flipHorizontalGrid ? backgroundMargin : -backgroundMargin; if (m_polarGraph) { // TODO optional placement of radial labels - YTrans up only if over background labelXTrans = m_scaleXWithBackground + labelMargin; @@ -1861,7 +1872,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa if (labelAutoAngle == 0.0f) { if (m_zFlipped) labelRotation.setY(180.0f); - if (m_yFlipped) { + if (m_yFlippedForGrid) { if (m_zFlipped) labelRotation.setY(180.0f); else @@ -1873,7 +1884,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } else { if (m_zFlipped) labelRotation.setY(180.0f); - if (m_yFlipped) { + if (m_yFlippedForGrid) { if (m_zFlipped) { if (m_xFlipped) { labelRotation.setX(90.0f - (labelAutoAngle - fractionCamX) @@ -1978,7 +1989,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa int labelCount = m_axisCacheX.labelCount(); GLfloat labelZTrans = 0.0f; - GLfloat labelYTrans = -backgroundMargin; + float labelYTrans = m_flipHorizontalGrid ? backgroundMargin : -backgroundMargin; if (m_polarGraph) labelYTrans += gridLineOffset + gridLineWidth; else @@ -1994,7 +2005,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa labelRotation = QVector3D(-90.0f, 90.0f, 0.0f); if (m_xFlipped) labelRotation.setY(-90.0f); - if (m_yFlipped) { + if (m_yFlippedForGrid) { if (m_xFlipped) labelRotation.setY(-90.0f); else @@ -2006,7 +2017,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa labelRotation.setY(-90.0f); else labelRotation.setY(90.0f); - if (m_yFlipped) { + if (m_yFlippedForGrid) { if (m_zFlipped) { if (m_xFlipped) { labelRotation.setX(90.0f - (2.0f * labelAutoAngle - fractionCamX) @@ -2055,10 +2066,12 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa QQuaternion totalRotation = Utils::calculateRotation(labelRotation); if (m_polarGraph) { - if (m_zFlipped != m_xFlipped) + if (!m_yFlippedForGrid && (m_zFlipped != m_xFlipped) + || m_yFlippedForGrid && (m_zFlipped == m_xFlipped)) { totalRotation *= m_zRightAngleRotation; - else + } else { totalRotation *= m_zRightAngleRotationNeg; + } } QVector3D labelTrans = QVector3D(0.0f, @@ -2108,7 +2121,8 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa hAlignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft; else if (gridPosition < 1.0f - centerMargin && gridPosition > 0.5f + centerMargin) hAlignment = m_zFlipped ? Qt::AlignLeft : Qt::AlignRight; - + if (m_yFlippedForGrid && vAlignment != Qt::AlignCenter) + vAlignment = (vAlignment == Qt::AlignTop) ? Qt::AlignBottom : Qt::AlignTop; alignment = Qt::AlignmentFlag(vAlignment | hAlignment); } else { labelTrans.setX(m_axisCacheX.labelPosition(label)); @@ -2417,6 +2431,11 @@ void Surface3DRenderer::updateSelectedPoint(const QPoint &position, QSurface3DSe m_selectionDirty = true; } +void Surface3DRenderer::updateFlipHorizontalGrid(bool flip) +{ + m_flipHorizontalGrid = flip; +} + void Surface3DRenderer::resetClickedStatus() { m_clickedPosition = Surface3DController::invalidSelectionPosition(); diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index a621fae3..b1ebf33e 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -78,6 +78,7 @@ private: QPoint m_clickedPosition; bool m_selectionTexturesDirty; GLuint m_noShadowTexture; + bool m_flipHorizontalGrid; public: explicit Surface3DRenderer(Surface3DController *controller); @@ -93,6 +94,7 @@ public: void updateScene(Q3DScene *scene); void updateSlicingActive(bool isSlicing); void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series); + void updateFlipHorizontalGrid(bool flip); inline QPoint clickedPosition() const { return m_clickedPosition; } void resetClickedStatus(); QVector3D convertPositionToTranslation(const QVector3D &position, bool isAbsolute); |