summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-06-19 09:54:03 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-06-26 10:43:30 +0300
commitec195a34594dea6145af5e8f2fedc2f9401d0f14 (patch)
tree407a1553a16461bd495c25a0b75af5289bd44210 /src
parent03baf7bc0b3bf07625e1111fe50c5262047ee302 (diff)
Polar graph support, phase one
- Polar property for toggling the polar mode - Example added. Example docs will be added in another patch once all of the functionality the example needs has been implemented. - Only surface graph supports polar so far. Scatter to be added later. Change-Id: I54d36f764ac1771ac88f73a5f3a2142f2309f6e8 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc13
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp22
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h26
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp152
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h17
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp23
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.cpp33
-rw-r--r--src/datavisualization/engine/qabstract3dgraph.h5
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp30
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp403
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h2
-rw-r--r--src/datavisualization/global/datavisualizationglobal_p.h1
-rw-r--r--src/datavisualization/theme/q3dtheme.cpp2
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp79
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h13
-rw-r--r--src/datavisualizationqml2/abstractdeclarative.cpp12
-rw-r--r--src/datavisualizationqml2/abstractdeclarative_p.h5
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.cpp6
20 files changed, 607 insertions, 239 deletions
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
index 2cc3eece..5afbc8c7 100644
--- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
@@ -153,6 +153,19 @@
*/
/*!
+ * \qmlproperty bool AbstractGraph3D::polar
+ * \since QtDataVisualization 1.2
+ *
+ * If \c {true}, the horizontal axes are changed into polar axes. The X axis becomes the
+ * angular axis and the Z axis becomes the radial axis.
+ * Polar mode is not available for bar graphs.
+ *
+ * Defaults to \c{false}.
+ *
+ * \sa orthoProjection, AbstractAxis3D::gridOffset, radialLabelOffset
+ */
+
+/*!
* \qmlmethod void AbstractGraph3D::clearSelection()
* Clears selection from all attached series.
*/
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
index 30434dca..e4fd0003 100644
--- a/src/datavisualization/engine/abstract3dcontroller.cpp
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -50,6 +50,7 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen
m_isCustomItemDirty(true),
m_isSeriesVisualsDirty(true),
m_renderPending(false),
+ m_isPolar(false),
m_measureFps(false),
m_numFrames(0),
m_currentFps(0.0)
@@ -176,6 +177,11 @@ void Abstract3DController::synchDataToRenderer()
m_renderer->updateTheme(m_themeManager->activeTheme());
+ if (m_changeTracker.polarChanged) {
+ m_renderer->updatePolar(m_isPolar);
+ m_changeTracker.polarChanged = false;
+ }
+
if (m_changeTracker.shadowQualityChanged) {
m_renderer->updateShadowQuality(m_shadowQuality);
m_changeTracker.shadowQualityChanged = false;
@@ -1521,4 +1527,20 @@ float Abstract3DController::aspectRatio()
return m_aspectRatio;
}
+void Abstract3DController::setPolar(bool enable)
+{
+ if (enable != m_isPolar) {
+ m_isPolar = enable;
+ m_changeTracker.polarChanged = true;
+ m_isDataDirty = true;
+ emit polarChanged(m_isPolar);
+ emitNeedRender();
+ }
+}
+
+bool Abstract3DController::isPolar() const
+{
+ return m_isPolar;
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index 0e4d1add..7d721b0c 100644
--- a/src/datavisualization/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -90,6 +90,7 @@ struct Abstract3DChangeBitField {
bool axisXTitleFixedChanged : 1;
bool axisYTitleFixedChanged : 1;
bool axisZTitleFixedChanged : 1;
+ bool polarChanged : 1;
Abstract3DChangeBitField() :
themeChanged(true),
@@ -133,7 +134,8 @@ struct Abstract3DChangeBitField {
axisZTitleVisibilityChanged(true),
axisXTitleFixedChanged(true),
axisYTitleFixedChanged(true),
- axisZTitleFixedChanged(true)
+ axisZTitleFixedChanged(true),
+ polarChanged(true)
{
}
};
@@ -175,6 +177,7 @@ protected:
bool m_isCustomItemDirty;
bool m_isSeriesVisualsDirty;
bool m_renderPending;
+ bool m_isPolar;
QList<QAbstract3DSeries *> m_seriesList;
@@ -261,6 +264,17 @@ public:
void setOrthoProjection(bool enable);
bool isOrthoProjection() const;
+ void setMeasureFps(bool enable);
+ inline bool measureFps() const { return m_measureFps; }
+ inline qreal currentFps() const { return m_currentFps; }
+
+ QAbstract3DGraph::ElementType selectedElement() const;
+
+ void setAspectRatio(float ratio);
+ float aspectRatio();
+ void setPolar(bool enable);
+ bool isPolar() const;
+
void emitNeedRender();
virtual void clearSelection() = 0;
@@ -320,17 +334,8 @@ public slots:
// Renderer callback handlers
void handleRequestShadowQuality(QAbstract3DGraph::ShadowQuality quality);
- void setMeasureFps(bool enable);
- inline bool measureFps() const { return m_measureFps; }
- inline qreal currentFps() const { return m_currentFps; }
-
- QAbstract3DGraph::ElementType selectedElement() const;
-
void updateCustomItem();
- void setAspectRatio(float ratio);
- float aspectRatio();
-
signals:
void shadowQualityChanged(QAbstract3DGraph::ShadowQuality quality);
void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler);
@@ -346,6 +351,7 @@ signals:
void orthoProjectionChanged(bool enabled);
void aspectRatioChanged(float ratio);
void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints);
+ void polarChanged(bool enabled);
protected:
virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation);
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
index 132a0514..56a5ba60 100644
--- a/src/datavisualization/engine/abstract3drenderer.cpp
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -25,8 +25,16 @@
#include "qcustom3ditem_p.h"
#include "qcustom3dlabel_p.h"
+#include <QtCore/qmath.h>
+
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+const qreal doublePi(M_PI * 2.0);
+const int polarGridRoundness(64);
+const qreal polarGridAngle(doublePi / qreal(polarGridRoundness));
+const float polarGridAngleDegrees(float(360.0 / qreal(polarGridRoundness)));
+const qreal polarGridHalfAngle(polarGridAngle / 2.0);
+
Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
: QObject(0),
m_hasNegativeValues(false),
@@ -37,6 +45,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_cachedSelectionMode(QAbstract3DGraph::SelectionNone),
m_cachedOptimizationHint(QAbstract3DGraph::OptimizationDefault),
m_textureHelper(0),
+ m_depthTexture(0),
m_cachedScene(new Q3DScene()),
m_selectionDirty(true),
m_selectionState(SelectNone),
@@ -55,7 +64,15 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_backgroundObj(0),
m_gridLineObj(0),
m_labelObj(0),
- m_graphAspectRatio(2.0f)
+ m_graphAspectRatio(2.0f),
+ m_polarGraph(false),
+ m_xRightAngleRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f)),
+ m_yRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f)),
+ m_zRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f)),
+ m_xRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f)),
+ m_yRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f)),
+ m_zRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -90.0f)),
+ m_xFlipRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -180.0f))
{
QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
QObject::connect(this, &Abstract3DRenderer::needRender, controller,
@@ -89,7 +106,10 @@ Abstract3DRenderer::~Abstract3DRenderer()
ObjectHelper::releaseObjectHelper(this, m_gridLineObj);
ObjectHelper::releaseObjectHelper(this, m_labelObj);
- delete m_textureHelper;
+ if (m_textureHelper) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ delete m_textureHelper;
+ }
}
void Abstract3DRenderer::initializeOpenGL()
@@ -287,6 +307,14 @@ void Abstract3DRenderer::updateAspectRatio(float ratio)
updateCustomItemPositions();
}
+void Abstract3DRenderer::updatePolar(bool enable)
+{
+ m_polarGraph = enable;
+ foreach (SeriesRenderCache *cache, m_renderCacheList)
+ cache->setDataDirty(true);
+ updateCustomItemPositions();
+}
+
void Abstract3DRenderer::updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint)
{
m_cachedOptimizationHint = hint;
@@ -607,10 +635,9 @@ void Abstract3DRenderer::drawAxisTitleY(const QVector3D &sideLabelRotation,
QQuaternion titleRotation;
if (m_axisCacheY.isTitleFixed()) {
titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation)
- * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f);
+ * m_zRightAngleRotation;
} else {
- titleRotation = totalRotation
- * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f);
+ titleRotation = totalRotation * m_zRightAngleRotation;
}
dummyItem.setTranslation(titleTrans + titleOffsetVector);
@@ -793,7 +820,6 @@ void Abstract3DRenderer::loadLabelMesh()
QStringLiteral(":/defaultMeshes/plane"));
}
-
void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture)
{
m_textureHelper->deleteTexture(texture);
@@ -1131,4 +1157,118 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state,
}
}
+void Abstract3DRenderer::calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const
+{
+ // x is angular, z is radial
+ qreal angle = m_axisCacheX.formatter()->positionAt(dataPos.x()) * doublePi;
+ qreal radius = m_axisCacheZ.formatter()->positionAt(dataPos.z());
+
+ // Convert angle & radius to X and Z coords
+ x = float(radius * qSin(angle)) * m_graphAspectRatio;
+ z = -float(radius * qCos(angle)) * m_graphAspectRatio;
+}
+
+void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePos,
+ const QMatrix4x4 &projectionViewMatrix,
+ const QMatrix4x4 &depthMatrix)
+{
+ static QVector<QQuaternion> lineRotations;
+ if (!lineRotations.size()) {
+ lineRotations.resize(polarGridRoundness);
+ for (int j = 0; j < polarGridRoundness; j++) {
+ lineRotations[j] = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f,
+ polarGridAngleDegrees * float(j));
+ }
+ }
+ int gridLineCount = m_axisCacheZ.gridLineCount();
+ const QVector<float> &gridPositions = m_axisCacheZ.formatter()->gridPositions();
+ const QVector<float> &subGridPositions = m_axisCacheZ.formatter()->subGridPositions();
+ int mainSize = gridPositions.size();
+ QVector3D translateVector(0.0f, yFloorLinePos, 0.0f);
+ for (int i = 0; i < gridLineCount; i++) {
+ float gridPosition = (i >= mainSize)
+ ? subGridPositions.at(i - mainSize) : gridPositions.at(i);
+ float radiusFraction = m_graphAspectRatio * gridPosition;
+ QVector3D gridLineScaler(radiusFraction * float(qSin(polarGridHalfAngle)),
+ gridLineWidth, gridLineWidth);
+ translateVector.setZ(gridPosition * m_graphAspectRatio);
+ for (int j = 0; j < polarGridRoundness; j++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ modelMatrix.rotate(lineRotations.at(j));
+ itModelMatrix.rotate(lineRotations.at(j));
+ modelMatrix.translate(translateVector);
+ modelMatrix.scale(gridLineScaler);
+ itModelMatrix.scale(gridLineScaler);
+ modelMatrix.rotate(m_xRightAngleRotationNeg);
+ itModelMatrix.rotate(m_xRightAngleRotationNeg);
+ QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix;
+ shader->setUniformValue(shader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(shader, m_gridLineObj);
+ }
+#else
+ m_drawer->drawLine(shader);
+#endif
+ }
+ }
+}
+
+void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLinePos,
+ const QMatrix4x4 &projectionViewMatrix,
+ const QMatrix4x4 &depthMatrix)
+{
+ float halfRatio(m_graphAspectRatio / 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);
+ for (int i = 0; i < gridLineCount; i++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ float gridPosition = (i >= mainSize)
+ ? subGridPositions.at(i - mainSize) : gridPositions.at(i);
+ QQuaternion lineRotation = QQuaternion::fromAxisAndAngle(upVector, gridPosition * 360.0f);
+ modelMatrix.rotate(lineRotation);
+ itModelMatrix.rotate(lineRotation);
+ modelMatrix.translate(translateVector);
+ modelMatrix.scale(gridLineScaler);
+ itModelMatrix.scale(gridLineScaler);
+ modelMatrix.rotate(m_xRightAngleRotationNeg);
+ itModelMatrix.rotate(m_xRightAngleRotationNeg);
+ QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ shader->setUniformValue(shader->model(), modelMatrix);
+ shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed());
+ shader->setUniformValue(shader->MVP(), MVPMatrix);
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix;
+ shader->setUniformValue(shader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(shader, m_gridLineObj);
+ }
+#else
+ m_drawer->drawLine(shader);
+#endif
+ }
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index 325ac8e6..33337441 100644
--- a/src/datavisualization/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -125,6 +125,7 @@ public:
virtual void updateCustomItem(CustomRenderItem *renderItem);
virtual void updateAspectRatio(float ratio);
+ virtual void updatePolar(bool enable);
virtual QVector3D convertPositionToTranslation(const QVector3D &position,
bool isAbsolute) = 0;
@@ -155,6 +156,7 @@ public:
GLuint depthTexture, GLfloat shadowQuality);
#endif
QVector4D indexToSelectionColor(GLint index);
+ void calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const;
signals:
void needRender(); // Emit this if something in renderer causes need for another render pass.
@@ -197,6 +199,11 @@ protected:
void loadGridLineMesh();
void loadLabelMesh();
+ void drawRadialGrid(ShaderHelper *shader, float yFloorLinePos,
+ const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix);
+ void drawAngularGrid(ShaderHelper *shader, float yFloorLinePos,
+ const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix);
+
bool m_hasNegativeValues;
Q3DTheme *m_cachedTheme;
Drawer *m_drawer;
@@ -211,6 +218,7 @@ protected:
AxisRenderCache m_axisCacheY;
AxisRenderCache m_axisCacheZ;
TextureHelper *m_textureHelper;
+ GLuint m_depthTexture;
Q3DScene *m_cachedScene;
bool m_selectionDirty;
@@ -244,6 +252,15 @@ protected:
ObjectHelper *m_labelObj; // Shared reference
float m_graphAspectRatio;
+ bool m_polarGraph;
+
+ QQuaternion m_xRightAngleRotation;
+ QQuaternion m_yRightAngleRotation;
+ QQuaternion m_zRightAngleRotation;
+ QQuaternion m_xRightAngleRotationNeg;
+ QQuaternion m_yRightAngleRotationNeg;
+ QQuaternion m_zRightAngleRotationNeg;
+ QQuaternion m_xFlipRotation;
private:
friend class Abstract3DController;
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index f909c7d6..70310c23 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -31,7 +31,6 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
-const GLfloat gridLineWidth = 0.005f;
const bool sliceGridLabels = true;
Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
@@ -50,7 +49,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_backgroundShader(0),
m_labelShader(0),
m_bgrTexture(0),
- m_depthTexture(0),
m_selectionTexture(0),
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
@@ -421,7 +419,6 @@ void Bars3DRenderer::drawSlicedScene()
GLfloat barPosX = 0;
QVector3D lightPos;
QVector4D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor());
- static QQuaternion ninetyDegreeRotation = QQuaternion::fromAxisAndAngle(upVector, 90.0f);
// Specify viewport
glViewport(m_secondarySubViewport.x(),
@@ -698,7 +695,7 @@ void Bars3DRenderer::drawSlicedScene()
barPosX = item.translation().x();
} else {
barPosX = -(item.translation().z()); // flip z; frontmost bar to the left
- barRotation *= ninetyDegreeRotation;
+ barRotation *= m_yRightAngleRotation;
}
modelMatrix.translate(barPosX, barPosY, 0.0f);
@@ -1701,9 +1698,9 @@ void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleF
modelMatrix.scale(backgroundScaler);
if (m_yFlipped)
- modelMatrix.rotate(90.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xRightAngleRotation);
else
- modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xRightAngleRotationNeg);
itModelMatrix = modelMatrix;
@@ -1835,9 +1832,9 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa
QVector3D gridLineScaler(rowScaleFactor, gridLineWidth, gridLineWidth);
if (m_yFlipped)
- lineRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f);
+ lineRotation = m_xRightAngleRotation;
else
- lineRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f);
+ lineRotation = m_xRightAngleRotationNeg;
// Floor lines: rows
for (GLfloat row = 0.0f; row <= m_cachedRowCount; row++) {
@@ -1879,7 +1876,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa
// Floor lines: columns
#if defined(QT_OPENGL_ES_2)
- lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineRotation = m_yRightAngleRotation;
#endif
gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor);
for (GLfloat bar = 0.0f; bar <= m_cachedColumnCount; bar++) {
@@ -1939,8 +1936,8 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa
modelMatrix.scale(gridLineScaler);
itModelMatrix.scale(gridLineScaler);
if (m_zFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xFlipRotation);
+ itModelMatrix.rotate(m_xFlipRotation);
}
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -1973,9 +1970,9 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa
xWallLinePosition = -xWallLinePosition;
if (m_xFlipped)
- lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f);
+ lineRotation = m_yRightAngleRotationNeg;
else
- lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineRotation = m_yRightAngleRotation;
gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor);
for (int line = 0; line < gridLineCount; line++) {
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index 29835741..466f7bed 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -68,7 +68,6 @@ private:
ShaderHelper *m_backgroundShader;
ShaderHelper *m_labelShader;
GLuint m_bgrTexture;
- GLuint m_depthTexture;
GLuint m_selectionTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp
index b8fa92e8..6240f714 100644
--- a/src/datavisualization/engine/qabstract3dgraph.cpp
+++ b/src/datavisualization/engine/qabstract3dgraph.cpp
@@ -591,8 +591,15 @@ qreal QAbstract3DGraph::currentFps() const
* \property QAbstract3DGraph::orthoProjection
* \since QtDataVisualization 1.1
*
- * If \c {true}, orthographic projection will be used for displaying the graph. Defaults to \c{false}.
+ * If \c {true}, orthographic projection will be used for displaying the graph.
+ * \note Orthographic projection can be used to create 2D graphs by replacing the default input
+ * handler with one that doesn't allow rotating the graph and setting the camera to view the graph
+ * directly from the side or from the top. Also, axis labels typically need to be rotated when
+ * viewing the graph from the sides.
+ * Defaults to \c{false}.
* \note Shadows will be disabled when set to \c{true}.
+ *
+ * \sa QAbstract3DAxis::labelAutoRotation, Q3DCamera::cameraPreset
*/
void QAbstract3DGraph::setOrthoProjection(bool enable)
{
@@ -646,6 +653,28 @@ QAbstract3DGraph::OptimizationHints QAbstract3DGraph::optimizationHints() const
}
/*!
+ * \property QAbstract3DGraph::polar
+ * \since QtDataVisualization 1.2
+ *
+ * If \c {true}, the horizontal axes are changed into polar axes. The X axis becomes the
+ * angular axis and the Z axis becomes the radial axis.
+ * Polar mode is not available for bar graphs.
+ *
+ * Defaults to \c{false}.
+ *
+ * \sa orthoProjection, QAbstract3DAxis::gridOffset, radialLabelOffset
+ */
+void QAbstract3DGraph::setPolar(bool enable)
+{
+ d_ptr->m_visualController->setPolar(enable);
+}
+
+bool QAbstract3DGraph::isPolar() const
+{
+ return d_ptr->m_visualController->isPolar();
+}
+
+/*!
* \internal
*/
bool QAbstract3DGraph::event(QEvent *event)
@@ -795,6 +824,8 @@ void QAbstract3DGraphPrivate::setVisualController(Abstract3DController *controll
QObject::connect(m_visualController, &Abstract3DController::aspectRatioChanged, q_ptr,
&QAbstract3DGraph::aspectRatioChanged);
+ QObject::connect(m_visualController, &Abstract3DController::polarChanged, q_ptr,
+ &QAbstract3DGraph::polarChanged);
}
void QAbstract3DGraphPrivate::handleDevicePixelRatioChange()
diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h
index 59f61aae..ca673358 100644
--- a/src/datavisualization/engine/qabstract3dgraph.h
+++ b/src/datavisualization/engine/qabstract3dgraph.h
@@ -50,6 +50,7 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected Q
Q_PROPERTY(ElementType selectedElement READ selectedElement NOTIFY selectedElementChanged)
Q_PROPERTY(qreal aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged)
Q_PROPERTY(OptimizationHints optimizationHints READ optimizationHints WRITE setOptimizationHints NOTIFY optimizationHintsChanged)
+ Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged)
protected:
explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format,
@@ -150,6 +151,9 @@ public:
void setOptimizationHints(OptimizationHints hints);
OptimizationHints optimizationHints() const;
+ void setPolar(bool enable);
+ bool isPolar() const;
+
protected:
bool event(QEvent *event);
void resizeEvent(QResizeEvent *event);
@@ -173,6 +177,7 @@ signals:
void orthoProjectionChanged(bool enabled);
void aspectRatioChanged(qreal ratio);
void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints);
+ void polarChanged(bool enabled);
private:
Q_DISABLE_COPY(QAbstract3DGraph)
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 7ac81552..f6b044f6 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -38,7 +38,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
const GLfloat defaultMinSize = 0.01f;
const GLfloat defaultMaxSize = 0.1f;
const GLfloat itemScaler = 3.0f;
-const GLfloat gridLineWidth = 0.005f;
Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
: Abstract3DRenderer(controller),
@@ -54,7 +53,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_backgroundShader(0),
m_labelShader(0),
m_bgrTexture(0),
- m_depthTexture(0),
m_selectionTexture(0),
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
@@ -1006,7 +1004,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.scale(bgScale);
// If we're viewing from below, background object must be flipped
if (m_yFlipped) {
- modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+ modelMatrix.rotate(m_xFlipRotation);
modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f);
} else {
modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
@@ -1095,14 +1093,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
QQuaternion lineXRotation;
if (m_xFlipped)
- lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f);
+ lineYRotation = m_yRightAngleRotationNeg;
else
- lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineYRotation = m_yRightAngleRotation;
if (m_yFlipped)
- lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f);
+ lineXRotation = m_xRightAngleRotation;
else
- lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f);
+ lineXRotation = m_xRightAngleRotationNeg;
GLfloat yFloorLinePosition = -1.0f - m_backgroundMargin + gridLineOffset;
if (m_yFlipped)
@@ -1189,8 +1187,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
modelMatrix.rotate(lineYRotation);
itModelMatrix.rotate(lineYRotation);
#else
- modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
- itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
+ modelMatrix.rotate(m_zRightAngleRotation);
+ itModelMatrix.rotate(m_zRightAngleRotation);
#endif
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -1221,7 +1219,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
// Columns (= X)
if (m_axisCacheX.segmentCount() > 0) {
#if defined(QT_OPENGL_ES_2)
- lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineXRotation = m_yRightAngleRotation;
#endif
// Floor lines
int gridLineCount = m_axisCacheX.gridLineCount();
@@ -1301,12 +1299,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
#if !defined(QT_OPENGL_ES_2)
if (m_zFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xFlipRotation);
+ itModelMatrix.rotate(m_xFlipRotation);
}
#else
- modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
- itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
+ modelMatrix.rotate(m_zRightAngleRotation);
+ itModelMatrix.rotate(m_zRightAngleRotation);
#endif
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -1368,8 +1366,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
itModelMatrix.scale(gridLineScaler);
if (m_zFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xFlipRotation);
+ itModelMatrix.rotate(m_xFlipRotation);
}
MVPMatrix = projectionViewMatrix * modelMatrix;
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index 7f213179..b0b1e411 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -61,7 +61,6 @@ private:
ShaderHelper *m_backgroundShader;
ShaderHelper *m_labelShader;
GLuint m_bgrTexture;
- GLuint m_depthTexture;
GLuint m_selectionTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index 60e57529..60e501f1 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -33,7 +33,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
// Margin for background (1.10 make it 10% larger to avoid
// selection ball being drawn inside background)
const GLfloat backgroundMargin = 1.1f;
-const GLfloat gridLineWidth = 0.005f;
const GLfloat sliceZScale = 0.1f;
const GLfloat sliceUnits = 2.5f;
const uint greenMultiplier = 256;
@@ -53,12 +52,10 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
m_selectionShader(0),
m_labelShader(0),
m_heightNormalizer(0.0f),
- m_scaleFactor(0.0f),
m_scaleX(0.0f),
m_scaleZ(0.0f),
m_scaleXWithBackground(0.0f),
m_scaleZWithBackground(0.0f),
- m_depthTexture(0),
m_depthModelTexture(0),
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
@@ -301,10 +298,13 @@ void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow>
srcArray->at(row)->at(j + sampleSpace.x());
}
- if (cache->isFlatShadingEnabled())
- cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y());
- else
- cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y());
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y(),
+ m_polarGraph);
+ } else {
+ cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y(),
+ m_polarGraph);
+ }
}
if (updateBuffers)
cache->surfaceObject()->uploadBuffers();
@@ -343,9 +343,9 @@ void Surface3DRenderer::updateItems(const QVector<Surface3DController::ChangeIte
(*(dstArray.at(y)))[x] = srcArray->at(point.x())->at(point.y());
if (cache->isFlatShadingEnabled())
- cache->surfaceObject()->updateCoarseItem(dstArray, y, x);
+ cache->surfaceObject()->updateCoarseItem(dstArray, y, x, m_polarGraph);
else
- cache->surfaceObject()->updateSmoothItem(dstArray, y, x);
+ cache->surfaceObject()->updateSmoothItem(dstArray, y, x, m_polarGraph);
}
if (updateBuffers)
cache->surfaceObject()->uploadBuffers();
@@ -538,10 +538,12 @@ void Surface3DRenderer::updateSliceObject(SurfaceSeriesRenderCache *cache, const
QRect sliceRect(0, 0, sliceRow->size(), 2);
if (sliceRow->size() > 0) {
- if (cache->isFlatShadingEnabled())
- cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, true, flipZX);
- else
- cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, true, flipZX);
+ if (cache->isFlatShadingEnabled()) {
+ cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, true, false, flipZX);
+ } else {
+ cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, true, false,
+ flipZX);
+ }
}
}
@@ -902,8 +904,8 @@ void Surface3DRenderer::drawSlicedScene()
modelMatrix.scale(gridLineScaleY);
itModelMatrix.scale(gridLineScaleY);
#if (defined QT_OPENGL_ES_2)
- modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
- itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
+ modelMatrix.rotate(m_zRightAngleRotation);
+ itModelMatrix.rotate(m_zRightAngleRotation);
#endif
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -1365,7 +1367,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
// If we're viewing from below, background object must be flipped
if (m_yFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xFlipRotation);
modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f);
} else {
modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
@@ -1461,205 +1463,213 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
QQuaternion lineXRotation;
if (m_xFlipped)
- lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f);
+ lineYRotation = m_yRightAngleRotationNeg;
else
- lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineYRotation = m_yRightAngleRotation;
if (m_yFlipped)
- lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f);
+ lineXRotation = m_xRightAngleRotation;
else
- lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f);
+ lineXRotation = m_xRightAngleRotationNeg;
- GLfloat yFloorLinePosition = -backgroundMargin + gridLineOffset;
+ float yFloorLinePosition = -backgroundMargin + gridLineOffset;
if (m_yFlipped)
yFloorLinePosition = -yFloorLinePosition;
// Rows (= Z)
if (m_axisCacheZ.segmentCount() > 0) {
- // Floor lines
int gridLineCount = m_axisCacheZ.gridLineCount();
+ // Floor lines
+ if (m_polarGraph) {
+ drawRadialGrid(lineShader, yFloorLinePosition, projectionViewMatrix,
+ depthProjectionViewMatrix);
+ } else {
+ for (int line = 0; line < gridLineCount; line++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
- for (int line = 0; line < gridLineCount; line++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- modelMatrix.translate(0.0f, yFloorLinePosition,
- m_axisCacheZ.gridLinePosition(line));
+ modelMatrix.translate(0.0f, yFloorLinePosition,
+ m_axisCacheZ.gridLinePosition(line));
- modelMatrix.scale(gridLineScaleX);
- itModelMatrix.scale(gridLineScaleX);
+ modelMatrix.scale(gridLineScaleX);
+ itModelMatrix.scale(gridLineScaleX);
- modelMatrix.rotate(lineXRotation);
- itModelMatrix.rotate(lineXRotation);
+ modelMatrix.rotate(lineXRotation);
+ itModelMatrix.rotate(lineXRotation);
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- // Set the rest of the shader bindings
- lineShader->setUniformValue(lineShader->model(), modelMatrix);
- lineShader->setUniformValue(lineShader->nModel(),
- itModelMatrix.inverted().transposed());
- lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
- } else {
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj);
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
#else
- m_drawer->drawLine(lineShader);
+ m_drawer->drawLine(lineShader);
#endif
- }
-
- // Side wall lines
- GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset;
+ }
+ // Side wall lines
+ GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset;
- if (!m_xFlipped)
- lineXTrans = -lineXTrans;
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
- for (int line = 0; line < gridLineCount; line++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
+ for (int line = 0; line < gridLineCount; line++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
- modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line));
+ modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line));
- modelMatrix.scale(gridLineScaleY);
- itModelMatrix.scale(gridLineScaleY);
+ modelMatrix.scale(gridLineScaleY);
+ itModelMatrix.scale(gridLineScaleY);
#if !defined(QT_OPENGL_ES_2)
- modelMatrix.rotate(lineYRotation);
- itModelMatrix.rotate(lineYRotation);
+ modelMatrix.rotate(lineYRotation);
+ itModelMatrix.rotate(lineYRotation);
#else
- modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
- itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
+ modelMatrix.rotate(m_zRightAngleRotation);
+ itModelMatrix.rotate(m_zRightAngleRotation);
#endif
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- // Set the rest of the shader bindings
- lineShader->setUniformValue(lineShader->model(), modelMatrix);
- lineShader->setUniformValue(lineShader->nModel(),
- itModelMatrix.inverted().transposed());
- lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
- } else {
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj);
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
#else
- m_drawer->drawLine(lineShader);
+ m_drawer->drawLine(lineShader);
#endif
+ }
}
}
// Columns (= X)
if (m_axisCacheX.segmentCount() > 0) {
#if defined(QT_OPENGL_ES_2)
- lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f);
+ lineXRotation = m_yRightAngleRotation;
#endif
// Floor lines
int gridLineCount = m_axisCacheX.gridLineCount();
- for (int line = 0; line < gridLineCount; line++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
+ if (m_polarGraph) {
+ drawAngularGrid(lineShader, yFloorLinePosition, projectionViewMatrix,
+ depthProjectionViewMatrix);
+ } else {
+ for (int line = 0; line < gridLineCount; line++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
- modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition,
- 0.0f);
+ modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition,
+ 0.0f);
- modelMatrix.scale(gridLineScaleZ);
- itModelMatrix.scale(gridLineScaleZ);
+ modelMatrix.scale(gridLineScaleZ);
+ itModelMatrix.scale(gridLineScaleZ);
- modelMatrix.rotate(lineXRotation);
- itModelMatrix.rotate(lineXRotation);
+ modelMatrix.rotate(lineXRotation);
+ itModelMatrix.rotate(lineXRotation);
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- // Set the rest of the shader bindings
- lineShader->setUniformValue(lineShader->model(), modelMatrix);
- lineShader->setUniformValue(lineShader->nModel(),
- itModelMatrix.inverted().transposed());
- lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
- } else {
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj);
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
#else
- m_drawer->drawLine(lineShader);
+ m_drawer->drawLine(lineShader);
#endif
- }
+ }
- // Back wall lines
- GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset;
+ // Back wall lines
+ GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset;
- if (!m_zFlipped)
- lineZTrans = -lineZTrans;
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans;
- for (int line = 0; line < gridLineCount; line++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
+ for (int line = 0; line < gridLineCount; line++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
- modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans);
+ modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans);
- modelMatrix.scale(gridLineScaleY);
- itModelMatrix.scale(gridLineScaleY);
+ modelMatrix.scale(gridLineScaleY);
+ itModelMatrix.scale(gridLineScaleY);
#if !defined(QT_OPENGL_ES_2)
- if (m_zFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- }
+ if (m_zFlipped) {
+ modelMatrix.rotate(m_xFlipRotation);
+ itModelMatrix.rotate(m_xFlipRotation);
+ }
#else
- modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
- itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f);
+ modelMatrix.rotate(m_zRightAngleRotation);
+ itModelMatrix.rotate(m_zRightAngleRotation);
#endif
- MVPMatrix = projectionViewMatrix * modelMatrix;
+ MVPMatrix = projectionViewMatrix * modelMatrix;
- // Set the rest of the shader bindings
- lineShader->setUniformValue(lineShader->model(), modelMatrix);
- lineShader->setUniformValue(lineShader->nModel(),
- itModelMatrix.inverted().transposed());
- lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
- // Set shadow shader bindings
- QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
- lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
- } else {
- // Draw the object
- m_drawer->drawObject(lineShader, m_gridLineObj);
- }
+ if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) {
+ // Set shadow shader bindings
+ QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else {
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
#else
- m_drawer->drawLine(lineShader);
+ m_drawer->drawLine(lineShader);
#endif
+ }
}
}
@@ -1684,8 +1694,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
itModelMatrix.scale(gridLineScaleX);
if (m_zFlipped) {
- modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f);
+ modelMatrix.rotate(m_xFlipRotation);
+ itModelMatrix.rotate(m_xFlipRotation);
}
MVPMatrix = projectionViewMatrix * modelMatrix;
@@ -1833,8 +1843,15 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
QVector3D positionZComp(0.0f, 0.0f, 0.0f);
if (m_axisCacheZ.segmentCount() > 0) {
int labelCount = m_axisCacheZ.labelCount();
- GLfloat labelXTrans = m_scaleXWithBackground + labelMargin;
- GLfloat labelYTrans = -backgroundMargin;
+ float labelXTrans = 0.0f;
+ float labelYTrans = -backgroundMargin;
+ if (m_polarGraph) {
+ // TODO optional placement of radial labels - YTrans up only if over background
+ labelXTrans = m_scaleXWithBackground + labelMargin;
+ //labelYTrans += gridLineOffset + gridLineWidth;
+ } else {
+ labelXTrans = m_scaleXWithBackground + labelMargin;
+ }
Qt::AlignmentFlag alignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight;
QVector3D labelRotation;
if (m_xFlipped)
@@ -1921,10 +1938,17 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
float offsetValue = 0.0f;
for (int label = startIndex; label != endIndex; label = label + indexStep) {
glPolygonOffset(offsetValue++ / -10.0f, 1.0f);
+ const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(label);
// Draw the label here
- labelTrans.setZ(m_axisCacheZ.labelPosition(label));
+ if (m_polarGraph) {
+ float direction = m_zFlipped ? -1.0f : 1.0f;
+ labelTrans.setZ((m_axisCacheZ.formatter()->labelPositions().at(label)
+ * -m_graphAspectRatio
+ + m_drawer->scaledFontSize() + gridLineWidth) * direction);
+ } else {
+ labelTrans.setZ(m_axisCacheZ.labelPosition(label));
+ }
m_dummyRenderItem.setTranslation(labelTrans);
- const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(label);
if (drawSelection) {
QVector4D labelColor = QVector4D(label / 255.0f, 0.0f, 0.0f,
@@ -1953,8 +1977,13 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
fractionCamX = activeCamera->xRotation() * labelAngleFraction;
int labelCount = m_axisCacheX.labelCount();
- GLfloat labelZTrans = m_scaleZWithBackground + labelMargin;
+ GLfloat labelZTrans = 0.0f;
GLfloat labelYTrans = -backgroundMargin;
+ if (m_polarGraph)
+ labelYTrans += gridLineOffset + gridLineWidth;
+ else
+ labelZTrans = m_scaleZWithBackground + labelMargin;
+
Qt::AlignmentFlag alignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight;
QVector3D labelRotation;
if (m_zFlipped)
@@ -2023,7 +2052,14 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
}
}
}
+
QQuaternion totalRotation = Utils::calculateRotation(labelRotation);
+ if (m_polarGraph) {
+ if (m_zFlipped != m_xFlipped)
+ totalRotation *= m_zRightAngleRotation;
+ else
+ totalRotation *= m_zRightAngleRotationNeg;
+ }
QVector3D labelTrans = QVector3D(0.0f,
labelYTrans,
@@ -2039,10 +2075,44 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa
indexStep = 1;
}
float offsetValue = 0.0f;
+ bool showLastLabel = false;
+ QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions();
+ int lastGridPosIndex = gridPositions.size() - 1;
+ if (gridPositions.size()
+ && (gridPositions.at(lastGridPosIndex) != 1.0f || gridPositions.at(0) != 0.0f)) {
+ // Avoid overlapping first and last label if they would get on same position
+ showLastLabel = true;
+ }
+
for (int label = startIndex; label != endIndex; label = label + indexStep) {
glPolygonOffset(offsetValue++ / -10.0f, 1.0f);
// Draw the label here
- labelTrans.setX(m_axisCacheX.labelPosition(label));
+ if (m_polarGraph) {
+ // Calculate angular position
+ if (label == lastGridPosIndex && !showLastLabel)
+ continue;
+ float gridPosition = m_axisCacheX.formatter()->gridPositions().at(label);
+ qreal angle = gridPosition * M_PI * 2.0;
+ labelTrans.setX((m_graphAspectRatio + labelMargin)* float(qSin(angle)));
+ labelTrans.setZ(-(m_graphAspectRatio + labelMargin) * float(qCos(angle)));
+ // Alignment depends on label angular position, as well as flips
+ Qt::AlignmentFlag vAlignment = Qt::AlignCenter;
+ Qt::AlignmentFlag hAlignment = Qt::AlignCenter;
+ const float centerMargin = 0.005f;
+ if (gridPosition < 0.25f - centerMargin || gridPosition > 0.75f + centerMargin)
+ vAlignment = m_zFlipped ? Qt::AlignTop : Qt::AlignBottom;
+ else if (gridPosition > 0.25f + centerMargin && gridPosition < 0.75f - centerMargin)
+ vAlignment = m_zFlipped ? Qt::AlignBottom : Qt::AlignTop;
+
+ if (gridPosition < 0.50f - centerMargin && gridPosition > centerMargin)
+ hAlignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft;
+ else if (gridPosition < 1.0f - centerMargin && gridPosition > 0.5f + centerMargin)
+ hAlignment = m_zFlipped ? Qt::AlignLeft : Qt::AlignRight;
+
+ alignment = Qt::AlignmentFlag(vAlignment | hAlignment);
+ } else {
+ labelTrans.setX(m_axisCacheX.labelPosition(label));
+ }
m_dummyRenderItem.setTranslation(labelTrans);
const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(label);
@@ -2298,13 +2368,18 @@ void Surface3DRenderer::calculateSceneScalingFactors()
m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min());
m_areaSize.setHeight(m_axisCacheZ.max() - m_axisCacheZ.min());
m_areaSize.setWidth(m_axisCacheX.max() - m_axisCacheX.min());
- m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
- m_scaleX = m_graphAspectRatio * m_areaSize.width() / m_scaleFactor;
- m_scaleZ = m_graphAspectRatio * m_areaSize.height() / m_scaleFactor;
+ float scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
+ if (m_polarGraph) {
+ m_scaleX = m_graphAspectRatio;
+ m_scaleZ = m_graphAspectRatio;
+ } else {
+ m_scaleX = m_graphAspectRatio * m_areaSize.width() / scaleFactor;
+ m_scaleZ = m_graphAspectRatio * m_areaSize.height() / scaleFactor;
+ }
m_scaleXWithBackground = m_scaleX + backgroundMargin - 1.0f;
m_scaleZWithBackground = m_scaleZ + backgroundMargin - 1.0f;
- float factorScaler = 2.0f * m_graphAspectRatio / m_scaleFactor;
+ float factorScaler = 2.0f * m_graphAspectRatio / scaleFactor;
m_axisCacheX.setScale(factorScaler * m_areaSize.width());
m_axisCacheZ.setScale(-factorScaler * m_areaSize.height());
m_axisCacheX.setTranslate(-m_axisCacheX.scale() / 2.0f);
@@ -2327,10 +2402,12 @@ void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dime
QSurfaceDataArray &dataArray = cache->dataArray();
const QRect &sampleSpace = cache->sampleSpace();
- if (cache->isFlatShadingEnabled())
- cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged);
- else
- cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged);
+ if (cache->isFlatShadingEnabled()) {
+ cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged, m_polarGraph);
+ } else {
+ cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged,
+ m_polarGraph);
+ }
}
void Surface3DRenderer::updateSelectedPoint(const QPoint &position, QSurface3DSeries *series)
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index efa8ff7e..a621fae3 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -57,12 +57,10 @@ private:
ShaderHelper *m_selectionShader;
ShaderHelper *m_labelShader;
GLfloat m_heightNormalizer;
- GLfloat m_scaleFactor;
GLfloat m_scaleX;
GLfloat m_scaleZ;
GLfloat m_scaleXWithBackground;
GLfloat m_scaleZWithBackground;
- GLuint m_depthTexture;
GLuint m_depthModelTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
diff --git a/src/datavisualization/global/datavisualizationglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h
index abdac998..f1f51309 100644
--- a/src/datavisualization/global/datavisualizationglobal_p.h
+++ b/src/datavisualization/global/datavisualizationglobal_p.h
@@ -69,6 +69,7 @@ static const GLfloat gradientTextureWidth = 2.0f;
static const GLfloat uniformTextureHeight = 64.0f;
static const GLfloat uniformTextureWidth = 2.0f;
static const GLfloat labelMargin = 0.05f;
+static const GLfloat gridLineWidth = 0.005f;
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/theme/q3dtheme.cpp b/src/datavisualization/theme/q3dtheme.cpp
index 97ff8f81..70397e23 100644
--- a/src/datavisualization/theme/q3dtheme.cpp
+++ b/src/datavisualization/theme/q3dtheme.cpp
@@ -679,7 +679,7 @@ QLinearGradient Q3DTheme::multiHighlightGradient() const
/*!
* \property Q3DTheme::lightStrength
*
- * Specular light strength for the whole graph. Value must be 0.0f and 10.0f.
+ * Specular light strength for the whole graph. Value must be between 0.0f and 10.0f.
*/
void Q3DTheme::setLightStrength(float strength)
{
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
index d999ba90..f8675912 100644
--- a/src/datavisualization/utils/surfaceobject.cpp
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -30,7 +30,8 @@ SurfaceObject::SurfaceObject(Surface3DRenderer *renderer)
m_gridIndexCount(0),
m_axisCacheX(renderer->m_axisCacheX),
m_axisCacheY(renderer->m_axisCacheY),
- m_axisCacheZ(renderer->m_axisCacheZ)
+ m_axisCacheZ(renderer->m_axisCacheZ),
+ m_renderer(renderer)
{
m_indicesType = GL_UNSIGNED_INT;
@@ -49,7 +50,7 @@ SurfaceObject::~SurfaceObject()
}
void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
- bool changeGeometry, bool flipXZ)
+ bool changeGeometry, bool polar, bool flipXZ)
{
m_columns = space.width();
m_rows = space.height();
@@ -75,9 +76,16 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
const QSurfaceDataRow &p = *dataArray.at(i);
for (int j = 0; j < m_columns; j++) {
const QSurfaceDataItem &data = p.at(j);
- float normalizedX = xCache.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ // Slice don't use polar, so don't care about flip
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = xCache.positionAt(data.x());
+ normalizedZ = zCache.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = zCache.positionAt(data.z());
m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ);
if (changeGeometry)
uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY);
@@ -137,7 +145,7 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR
createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry);
}
-void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex)
+void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar)
{
// Update vertices
int p = rowIndex * m_columns;
@@ -145,9 +153,15 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI
for (int j = 0; j < m_columns; j++) {
const QSurfaceDataItem &data = dataRow.at(j);
- float normalizedX = m_axisCacheX.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = m_axisCacheX.positionAt(data.x());
+ normalizedZ = m_axisCacheZ.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = m_axisCacheZ.positionAt(data.z());
m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ);
}
@@ -196,13 +210,20 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI
}
}
-void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column)
+void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column,
+ bool polar)
{
// Update a vertice
const QSurfaceDataItem &data = dataArray.at(row)->at(column);
- float normalizedX = m_axisCacheX.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = m_axisCacheX.positionAt(data.x());
+ normalizedZ = m_axisCacheZ.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = m_axisCacheZ.positionAt(data.z());
m_vertices[row * m_columns + column] = QVector3D(normalizedX, normalizedY, normalizedZ);
// Create normals
@@ -331,7 +352,7 @@ void SurfaceObject::createSmoothGridlineIndices(int x, int y, int endX, int endY
}
void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space,
- bool changeGeometry, bool flipXZ)
+ bool changeGeometry, bool polar, bool flipXZ)
{
m_columns = space.width();
m_rows = space.height();
@@ -362,9 +383,16 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
const QSurfaceDataRow &row = *dataArray.at(i);
for (int j = 0; j < m_columns; j++) {
const QSurfaceDataItem &data = row.at(j);
- float normalizedX = xCache.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ // Slice don't use polar, so don't care about flip
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = xCache.positionAt(data.x());
+ normalizedZ = zCache.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = zCache.positionAt(data.z());
m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ);
if (changeGeometry)
uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY);
@@ -438,7 +466,7 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s
delete[] indices;
}
-void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex)
+void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar)
{
int colLimit = m_columns - 1;
int doubleColumns = m_columns * 2 - 2;
@@ -448,9 +476,15 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI
for (int j = 0; j < m_columns; j++) {
const QSurfaceDataItem &data = dataRow.at(j);
- float normalizedX = m_axisCacheX.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = m_axisCacheX.positionAt(data.x());
+ normalizedZ = m_axisCacheZ.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = m_axisCacheZ.positionAt(data.z());
m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ);
if (j > 0 && j < colLimit) {
@@ -486,7 +520,8 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI
}
}
-void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column)
+void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column,
+ bool polar)
{
int colLimit = m_columns - 1;
int doubleColumns = m_columns * 2 - 2;
@@ -494,9 +529,15 @@ void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row
// Update a vertice
int p = row * doubleColumns + column * 2 - (column > 0);
const QSurfaceDataItem &data = dataArray.at(row)->at(column);
- float normalizedX = m_axisCacheX.positionAt(data.x());
+ float normalizedX;
+ float normalizedZ;
+ if (polar) {
+ m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ);
+ } else {
+ normalizedX = m_axisCacheX.positionAt(data.x());
+ normalizedZ = m_axisCacheZ.positionAt(data.z());
+ }
float normalizedY = m_axisCacheY.positionAt(data.y());
- float normalizedZ = m_axisCacheZ.positionAt(data.z());
m_vertices[p] = QVector3D(normalizedX, normalizedY, normalizedZ);
p++;
diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index 9c18dcb2..54e6dec3 100644
--- a/src/datavisualization/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -54,13 +54,13 @@ public:
~SurfaceObject();
void setUpData(const QSurfaceDataArray &dataArray, const QRect &space,
- bool changeGeometry, bool flipXZ = false);
+ bool changeGeometry, bool polar, bool flipXZ = false);
void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
- bool changeGeometry, bool flipXZ = false);
- void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex);
- void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow);
- void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column);
- void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column);
+ bool changeGeometry, bool polar, bool flipXZ = false);
+ void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar);
+ void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow, bool polar);
+ void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar);
+ void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar);
void createSmoothIndices(int x, int y, int endX, int endY);
void createCoarseIndices(int x, int y, int columns, int rows);
void createSmoothGridlineIndices(int x, int y, int endX, int endY);
@@ -90,6 +90,7 @@ private:
AxisRenderCache &m_axisCacheX;
AxisRenderCache &m_axisCacheY;
AxisRenderCache &m_axisCacheZ;
+ Surface3DRenderer *m_renderer;
};
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp
index f7ccbf21..30acc9e4 100644
--- a/src/datavisualizationqml2/abstractdeclarative.cpp
+++ b/src/datavisualizationqml2/abstractdeclarative.cpp
@@ -329,6 +329,8 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller)
&AbstractDeclarative::aspectRatioChanged);
QObject::connect(m_controller.data(), &Abstract3DController::optimizationHintsChanged, this,
&AbstractDeclarative::handleOptimizationHintChange);
+ QObject::connect(m_controller.data(), &Abstract3DController::polarChanged, this,
+ &AbstractDeclarative::polarChanged);
}
void AbstractDeclarative::activateOpenGLContext(QQuickWindow *window)
@@ -724,6 +726,16 @@ AbstractDeclarative::OptimizationHints AbstractDeclarative::optimizationHints()
return OptimizationHints(intmode);
}
+void AbstractDeclarative::setPolar(bool enable)
+{
+ m_controller->setPolar(enable);
+}
+
+bool AbstractDeclarative::isPolar() const
+{
+ return m_controller->isPolar();
+}
+
void AbstractDeclarative::windowDestroyed(QObject *obj)
{
// Remove destroyed window from window lists
diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h
index dfcd9537..cd3d6134 100644
--- a/src/datavisualizationqml2/abstractdeclarative_p.h
+++ b/src/datavisualizationqml2/abstractdeclarative_p.h
@@ -72,6 +72,7 @@ class AbstractDeclarative : public QQuickItem
Q_PROPERTY(ElementType selectedElement READ selectedElement NOTIFY selectedElementChanged REVISION 1)
Q_PROPERTY(qreal aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged REVISION 1)
Q_PROPERTY(OptimizationHints optimizationHints READ optimizationHints WRITE setOptimizationHints NOTIFY optimizationHintsChanged REVISION 1)
+ Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged REVISION 2)
public:
enum SelectionFlag {
@@ -193,6 +194,9 @@ public:
void setOptimizationHints(OptimizationHints hints);
OptimizationHints optimizationHints() const;
+ void setPolar(bool enable);
+ bool isPolar() const;
+
public slots:
virtual void handleAxisXChanged(QAbstract3DAxis *axis) = 0;
virtual void handleAxisYChanged(QAbstract3DAxis *axis) = 0;
@@ -230,6 +234,7 @@ signals:
Q_REVISION(1) void orthoProjectionChanged(bool enabled);
Q_REVISION(1) void aspectRatioChanged(qreal ratio);
Q_REVISION(1) void optimizationHintsChanged(AbstractDeclarative::OptimizationHints hints);
+ Q_REVISION(2) void polarChanged(bool enabled);
private:
QPointer<Abstract3DController> m_controller;
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
index 09780dc5..c4c0bc70 100644
--- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
@@ -106,6 +106,12 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri)
// New metatypes
qRegisterMetaType<QAbstract3DGraph::ElementType>("QAbstract3DGraph::ElementType");
+
+ // QtDataVisualization 1.2
+
+ // New revisions
+ qmlRegisterUncreatableType<AbstractDeclarative, 2>(uri, 1, 2, "AbstractGraph3D",
+ QLatin1String("Trying to create uncreatable: AbstractGraph3D."));
}
QT_END_NAMESPACE_DATAVISUALIZATION