summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-06-25 13:00:55 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-06-26 10:43:39 +0300
commit36417dd3660f75c34328c3420bdd512436da86ff (patch)
treeb940d98d8df6a8a64adc1a638c57f20a4a955c5b /src/datavisualization/engine
parentec195a34594dea6145af5e8f2fedc2f9401d0f14 (diff)
Add flipHorizontalGrid property for surface
This property allows drawind the horizontal grid and axis labels on top of the graph rather than on the bottom. This is useful when surface graph is used for 2D spectrograms in orthographic mode, as otherwise the grid is covered by the surface itself. Particularly relevant for polar plots of the same. Task-number: QTRD-3184 Change-Id: I9dbcdbfc754e13af52d2cf31a1d9991ef4b241f7 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp22
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/q3dsurface.cpp21
-rw-r--r--src/datavisualization/engine/q3dsurface.h4
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp1
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp23
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h15
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp41
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h2
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);