diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-05 14:00:08 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-06 08:39:25 +0300 |
commit | dd99eb73740ad015a2a2d28481e5a2ca8ab1d7b1 (patch) | |
tree | bcbbd462e547cd958b1343412d0a14e920b5c453 /src/datavisualization/engine | |
parent | 73f127d8ef1937aa77ba0ec0be63f0bfd6cf92ab (diff) |
Enable camera targeting.
Also fix custom item positioning in absolute mode as it was completely
broken in bars and z-coord was flipped in others.
Clarified Q3DObject::position property usage, namely that it is reserved
for internal use for now.
Some refactoring also done.
Task-number: QTRD-2567
Change-Id: I5da65b83a2f8ecf20f8fd054e59748278ef1a714
Reviewed-by: Titta Heikkala <titta.heikkala@digia.com>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer.cpp | 35 | ||||
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer_p.h | 4 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3dcontroller.cpp | 10 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer.cpp | 93 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer_p.h | 16 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dcamera.cpp | 81 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dcamera.h | 5 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dcamera_p.h | 3 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dlight.cpp | 9 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dobject.cpp | 9 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dscene.cpp | 6 | ||||
-rw-r--r-- | src/datavisualization/engine/q3dscene_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 20 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer.cpp | 24 | ||||
-rw-r--r-- | src/datavisualization/engine/surface3drenderer_p.h | 2 |
16 files changed, 191 insertions, 130 deletions
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index c2ed43da..14cf7109 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -79,7 +79,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_xFlipRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -180.0f)), m_zFlipRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -180.0f)), m_vBackgroundMargin(0.1f), - m_hBackgroundMargin(0.1f) + m_hBackgroundMargin(0.1f), + m_oldCameraTarget(QVector3D(2000.0f, 2000.0f, 2000.0f)) // Just random invalid target { QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); QObject::connect(this, &Abstract3DRenderer::needRender, controller, @@ -220,10 +221,6 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) handleResize(); } - scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment); - // Set light position (rotate light with activeCamera, a bit above it (as set in defaultLightPos)) - scene->d_ptr->setLightPositionRelativeToCamera(defaultLightPos); - QPoint logicalPixelPosition = scene->selectionQueryPosition(); updateInputPosition(QPoint(logicalPixelPosition.x() * m_devicePixelRatio, logicalPixelPosition.y() * m_devicePixelRatio)); @@ -231,6 +228,8 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) // Synchronize the renderer scene to controller scene scene->d_ptr->sync(*m_cachedScene->d_ptr); + updateCameraViewport(); + if (Q3DScene::invalidSelectionPoint() == logicalPixelPosition) { updateSelectionState(SelectNone); } else { @@ -316,7 +315,6 @@ void Abstract3DRenderer::updateAspectRatio(float ratio) m_graphAspectRatio = ratio; foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - updateCustomItemPositions(); } void Abstract3DRenderer::updateHorizontalAspectRatio(float ratio) @@ -324,7 +322,6 @@ void Abstract3DRenderer::updateHorizontalAspectRatio(float ratio) m_graphHorizontalAspectRatio = ratio; foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - updateCustomItemPositions(); } void Abstract3DRenderer::updatePolar(bool enable) @@ -332,7 +329,6 @@ void Abstract3DRenderer::updatePolar(bool enable) m_polarGraph = enable; foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - updateCustomItemPositions(); } void Abstract3DRenderer::updateRadialLabelOffset(float offset) @@ -401,8 +397,6 @@ void Abstract3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orient foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - - updateCustomItemPositions(); } void Abstract3DRenderer::updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation, @@ -431,8 +425,6 @@ void Abstract3DRenderer::updateAxisReversed(QAbstract3DAxis::AxisOrientation ori axisCacheForOrientation(orientation).setReversed(enable); foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - - updateCustomItemPositions(); } void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, @@ -449,8 +441,6 @@ void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation or foreach (SeriesRenderCache *cache, m_renderCacheList) cache->setDataDirty(true); - - updateCustomItemPositions(); } void Abstract3DRenderer::updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation, @@ -1347,4 +1337,21 @@ float Abstract3DRenderer::calculatePolarBackgroundMargin() return maxNeededMargin; } +void Abstract3DRenderer::updateCameraViewport() +{ + QVector3D adjustedTarget = m_cachedScene->activeCamera()->target(); + fixCameraTarget(adjustedTarget); + if (m_oldCameraTarget != adjustedTarget) { + QVector3D cameraBase = cameraDistanceVector + adjustedTarget; + + m_cachedScene->activeCamera()->d_ptr->setBaseOrientation(cameraBase, + adjustedTarget, + upVector); + m_oldCameraTarget = adjustedTarget; + } + m_cachedScene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment); + // Set light position (i.e rotate light with activeCamera, a bit above it) + m_cachedScene->d_ptr->setLightPositionRelativeToCamera(defaultLightPos); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 40c7db0a..50370954 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -207,6 +207,8 @@ protected: const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix); float calculatePolarBackgroundMargin(); + virtual void fixCameraTarget(QVector3D &target) = 0; + void updateCameraViewport(); bool m_hasNegativeValues; Q3DTheme *m_cachedTheme; @@ -274,6 +276,8 @@ protected: float m_vBackgroundMargin; float m_hBackgroundMargin; + QVector3D m_oldCameraTarget; + private: friend class Abstract3DController; }; diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 3a240c24..bbec6967 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -114,12 +114,10 @@ void Bars3DController::synchDataToRenderer() m_changeTracker.selectedBarChanged = false; } - if (needSceneUpdate) { - // Since scene is updated before axis updates are handled, - // do another render pass for scene update - m_scene->d_ptr->m_sceneDirty = true; - emitNeedRender(); - } + // Since scene is updated before axis updates are handled, do another render pass to + // properly update controller side camera limits. + if (needSceneUpdate) + m_scene->d_ptr->markDirty(); } void Bars3DController::handleArrayReset() diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index cd6c1eb0..38fa3147 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -65,7 +65,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_scaleFactor(0), m_maxSceneSize(40.0f), m_visualSelectedBarPos(Bars3DController::invalidSelectionPosition()), - m_resetCameraBaseOrientation(true), m_selectedBarPos(Bars3DController::invalidSelectionPosition()), m_selectedSeriesCache(0), m_noZeroInRange(false), @@ -77,7 +76,9 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_keepSeriesUniform(false), m_haveUniformColorSeries(false), m_haveGradientSeries(false), - m_zeroPosition(0.0f) + m_zeroPosition(0.0f), + m_xScaleFactor(1.0f), + m_zScaleFactor(1.0f) { m_axisCacheY.setScale(2.0f); m_axisCacheY.setTranslate(-1.0f); @@ -130,6 +131,13 @@ void Bars3DRenderer::initializeOpenGL() loadBackgroundMesh(); } +void Bars3DRenderer::fixCameraTarget(QVector3D &target) +{ + target.setX(target.x() * m_xScaleFactor); + target.setY(0.0f); + target.setZ(target.z() * -m_zScaleFactor); +} + void Bars3DRenderer::updateData() { int minRow = m_axisCacheZ.min(); @@ -161,10 +169,10 @@ void Bars3DRenderer::updateData() GLfloat sceneRatio = qMin(GLfloat(newColumns) / GLfloat(newRows), GLfloat(newRows) / GLfloat(newColumns)); m_maxSceneSize = 2.0f * qSqrt(sceneRatio * newColumns * newRows); - // Calculate here and at setting bar specs - calculateSceneScalingFactors(); } + calculateSceneScalingFactors(); + m_zeroPosition = m_axisCacheY.formatter()->positionAt(0.0f); foreach (SeriesRenderCache *baseCache, m_renderCacheList) { @@ -388,14 +396,6 @@ void Bars3DRenderer::updateScene(Q3DScene *scene) } } - if (m_resetCameraBaseOrientation) { - // Set initial camera position. Also update if height adjustment has changed. - scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, - zeroVector, - upVector); - m_resetCameraBaseOrientation = false; - } - Abstract3DRenderer::updateScene(scene); updateSlicingActive(scene->isSlicingActive()); @@ -986,9 +986,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; - GLfloat rowScaleFactor = m_rowWidth / m_scaleFactor; - GLfloat columnScaleFactor = m_columnDepth / m_scaleFactor; - BarRenderItem *selectedBar(0); #if !defined(QT_OPENGL_ES_2) @@ -1185,8 +1182,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) Abstract3DRenderer::drawCustomItems(RenderingSelection, m_selectionShader, viewMatrix, projectionViewMatrix, depthProjectionViewMatrix, m_depthTexture, m_shadowQualityToShader); - drawLabels(true, activeCamera, viewMatrix, projectionMatrix, rowScaleFactor, - columnScaleFactor); + drawLabels(true, activeCamera, viewMatrix, projectionMatrix); glEnable(GL_DITHER); // Read color under cursor @@ -1216,8 +1212,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glStencilFunc(GL_ALWAYS, 1, 0xffffffff); // Draw background stencil - drawBackground(rowScaleFactor, columnScaleFactor, backgroundRotation, - depthProjectionViewMatrix, projectionViewMatrix, viewMatrix); + drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glEnable(GL_DEPTH_TEST); @@ -1255,12 +1250,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) #ifdef USE_REFLECTIONS glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - drawBackground(rowScaleFactor, columnScaleFactor, backgroundRotation, - depthProjectionViewMatrix, projectionViewMatrix, viewMatrix, 0.5f); + drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix, + 0.5f); glDisable(GL_BLEND); #else - drawBackground(rowScaleFactor, columnScaleFactor, backgroundRotation, - depthProjectionViewMatrix, projectionViewMatrix, viewMatrix); + drawBackground(backgroundRotation, depthProjectionViewMatrix, projectionViewMatrix, viewMatrix); #endif // Draw bars @@ -1270,8 +1264,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) startBar, stopBar, stepBar); // Draw grid lines - drawGridLines(rowScaleFactor, columnScaleFactor, depthProjectionViewMatrix, - projectionViewMatrix, viewMatrix); + drawGridLines(depthProjectionViewMatrix, projectionViewMatrix, viewMatrix); // Draw custom items Abstract3DRenderer::drawCustomItems(RenderingNormal, m_customItemShader, viewMatrix, @@ -1279,8 +1272,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_depthTexture, m_shadowQualityToShader); // Draw labels - drawLabels(false, activeCamera, viewMatrix, projectionMatrix, rowScaleFactor, - columnScaleFactor); + drawLabels(false, activeCamera, viewMatrix, projectionMatrix); // Handle selected bar label generation if (barSelectionFound) { @@ -1657,14 +1649,12 @@ bool Bars3DRenderer::drawBars(BarRenderItem **selectedBar, } #ifdef USE_REFLECTIONS -void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - GLfloat backgroundRotation, +void Bars3DRenderer::drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix, GLfloat reflection) #else -void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - GLfloat backgroundRotation, +void Bars3DRenderer::drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix) @@ -1683,7 +1673,7 @@ void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleF QMatrix4x4 MVPMatrix; QMatrix4x4 itModelMatrix; - QVector3D backgroundScaler(rowScaleFactor, 1.0f, columnScaleFactor); + QVector3D backgroundScaler(m_xScaleFactor, 1.0f, m_zScaleFactor); QVector4D backgroundColor = Utils::vectorFromColor(m_cachedTheme->backgroundColor()); #ifdef USE_REFLECTIONS backgroundColor.setW(backgroundColor.w() * reflection); @@ -1787,8 +1777,7 @@ void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleF } } -void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - const QMatrix4x4 &depthProjectionViewMatrix, +void Bars3DRenderer::drawGridLines(const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix) { @@ -1832,7 +1821,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa if (m_yFlipped) yFloorLinePosition = -yFloorLinePosition; - QVector3D gridLineScaler(rowScaleFactor, gridLineWidth, gridLineWidth); + QVector3D gridLineScaler(m_xScaleFactor, gridLineWidth, gridLineWidth); if (m_yFlipped) lineRotation = m_xRightAngleRotation; @@ -1881,7 +1870,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa #if defined(QT_OPENGL_ES_2) lineRotation = m_yRightAngleRotation; #endif - gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor); + gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, m_zScaleFactor); for (GLfloat bar = 0.0f; bar <= m_cachedColumnCount; bar++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; @@ -1923,11 +1912,11 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa // Wall lines: back wall int gridLineCount = m_axisCacheY.gridLineCount(); - GLfloat zWallLinePosition = -columnScaleFactor + gridLineOffset; + GLfloat zWallLinePosition = -m_zScaleFactor + gridLineOffset; if (m_zFlipped) zWallLinePosition = -zWallLinePosition; - gridLineScaler = QVector3D(rowScaleFactor, gridLineWidth, gridLineWidth); + gridLineScaler = QVector3D(m_xScaleFactor, gridLineWidth, gridLineWidth); for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; @@ -1968,7 +1957,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa } // Wall lines: side wall - GLfloat xWallLinePosition = -rowScaleFactor + gridLineOffset; + GLfloat xWallLinePosition = -m_xScaleFactor + gridLineOffset; if (m_xFlipped) xWallLinePosition = -xWallLinePosition; @@ -1977,7 +1966,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa else lineRotation = m_yRightAngleRotation; - gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor); + gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, m_zScaleFactor); for (int line = 0; line < gridLineCount; line++) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; @@ -2019,8 +2008,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa } void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamera, - const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, - GLfloat rowScaleFactor, GLfloat columnScaleFactor) { + const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix) { ShaderHelper *shader = 0; GLfloat alphaForValueSelection = labelValueAlpha / 255.0f; GLfloat alphaForRowSelection = labelRowAlpha / 255.0f; @@ -2052,8 +2040,8 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer int labelCount = m_axisCacheY.labelCount(); GLfloat labelMarginXTrans = labelMargin; GLfloat labelMarginZTrans = labelMargin; - GLfloat labelXTrans = rowScaleFactor; - GLfloat labelZTrans = columnScaleFactor; + GLfloat labelXTrans = m_xScaleFactor; + GLfloat labelZTrans = m_zScaleFactor; QVector3D backLabelRotation(0.0f, -90.0f, 0.0f); QVector3D sideLabelRotation(0.0f, 0.0f, 0.0f); Qt::AlignmentFlag backAlignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; @@ -2157,8 +2145,8 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer fractionCamY = activeCamera->yRotation() * labelAngleFraction; fractionCamX = activeCamera->xRotation() * labelAngleFraction; GLfloat labelYAdjustment = 0.005f; - GLfloat scaledRowWidth = rowScaleFactor; - GLfloat scaledColumnDepth = columnScaleFactor; + GLfloat scaledRowWidth = m_xScaleFactor; + GLfloat scaledColumnDepth = m_zScaleFactor; GLfloat colPosValue = scaledRowWidth + labelMargin; GLfloat rowPosValue = scaledColumnDepth + labelMargin; GLfloat rowPos = 0.0f; @@ -2580,8 +2568,17 @@ void Bars3DRenderer::calculateSceneScalingFactors() m_maxDimension = qMax(m_rowWidth, m_columnDepth); m_scaleFactor = qMin((m_cachedColumnCount * (m_maxDimension / m_maxSceneSize)), (m_cachedRowCount * (m_maxDimension / m_maxSceneSize))); + + // Single bar scaling m_scaleX = m_cachedBarThickness.width() / m_scaleFactor; m_scaleZ = m_cachedBarThickness.height() / m_scaleFactor; + + // Whole graph scale factors + m_xScaleFactor = m_rowWidth / m_scaleFactor; + m_zScaleFactor = m_columnDepth / m_scaleFactor; + + updateCameraViewport(); + updateCustomItemPositions(); } void Bars3DRenderer::calculateHeightAdjustment() @@ -2815,9 +2812,9 @@ QVector3D Bars3DRenderer::convertPositionToTranslation(const QVector3D &position / m_scaleFactor; yTrans = m_axisCacheY.positionAt(position.y()); } else { - xTrans = position.x() * m_scaleX; + xTrans = position.x() * m_xScaleFactor; yTrans = position.y() + m_backgroundAdjustment; - zTrans = position.z() * m_scaleZ; + zTrans = position.z() * -m_zScaleFactor; } return QVector3D(xTrans, yTrans, zTrans); } diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 466f7bed..cf29dc21 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -85,7 +85,6 @@ private: GLfloat m_scaleFactor; GLfloat m_maxSceneSize; QPoint m_visualSelectedBarPos; - bool m_resetCameraBaseOrientation; QPoint m_selectedBarPos; BarSeriesRenderCache *m_selectedSeriesCache; BarRenderItem m_dummyBarRenderItem; @@ -99,6 +98,8 @@ private: bool m_haveUniformColorSeries; bool m_haveGradientSeries; float m_zeroPosition; + float m_xScaleFactor; + float m_zScaleFactor; public: explicit Bars3DRenderer(Bars3DController *controller); @@ -118,6 +119,7 @@ public: protected: virtual void initializeOpenGL(); + virtual void fixCameraTarget(QVector3D &target); public slots: void updateMultiSeriesScaling(bool uniform); @@ -145,16 +147,14 @@ private: void drawSlicedScene(); void drawScene(GLuint defaultFboHandle); void drawLabels(bool drawSelection, const Q3DCamera *activeCamera, - const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix, - GLfloat rowScaleFactor, GLfloat columnScaleFactor); + const QMatrix4x4 &viewMatrix, const QMatrix4x4 &projectionMatrix); #ifdef USE_REFLECTIONS bool drawBars(BarRenderItem **selectedBar, const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix, GLint startRow, GLint stopRow, GLint stepRow, GLint startBar, GLint stopBar, GLint stepBar, GLfloat reflection = 1.0f); - void drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, + void drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix, GLfloat reflection = 1.0f); #else @@ -162,12 +162,10 @@ private: const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix, GLint startRow, GLint stopRow, GLint stepRow, GLint startBar, GLint stopBar, GLint stepBar); - void drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, + void drawBackground(GLfloat backgroundRotation, const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix); #endif - void drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFactor, - const QMatrix4x4 &depthProjectionViewMatrix, + void drawGridLines(const QMatrix4x4 &depthProjectionViewMatrix, const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &viewMatrix); diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp index 06fd570c..0c2a8d82 100644 --- a/src/datavisualization/engine/q3dcamera.cpp +++ b/src/datavisualization/engine/q3dcamera.cpp @@ -137,6 +137,19 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty vector3d Camera3D::target + * \since QtDataVisualization 1.2 + * + * Holds the camera \a target as a vector3d. Defaults to \c {vector3d(0.0, 0.0, 0.0)}. + * + * Valid coordinate values are between \c{-1.0...1.0}, where the edge values indicate + * the edges of the corresponding axis range. Any values outside this range are clamped to the edge. + * + * \note For bar graphs, the Y-coordinate is ignored and camera always targets a point on + * the horizontal background. + */ + +/*! * Constructs a new 3D camera with position set to origin, up direction facing towards the Y-axis * and looking at origin by default. An optional \a parent parameter can be given and is then passed * to QObject constructor. @@ -160,22 +173,11 @@ Q3DCamera::~Q3DCamera() */ void Q3DCamera::copyValuesFrom(const Q3DObject &source) { - Q3DObject::copyValuesFrom(source); + // Note: Do not copy values from parent, as we are handling the position internally const Q3DCamera &sourceCamera = static_cast<const Q3DCamera &>(source); - d_ptr->m_target.setX(sourceCamera.d_ptr->m_target.x()); - d_ptr->m_target.setY(sourceCamera.d_ptr->m_target.y()); - d_ptr->m_target.setZ(sourceCamera.d_ptr->m_target.z()); - - d_ptr->m_up.setX(sourceCamera.d_ptr->m_up.x()); - d_ptr->m_up.setY(sourceCamera.d_ptr->m_up.y()); - d_ptr->m_up.setZ(sourceCamera.d_ptr->m_up.z()); - - float *values = new float[16]; - sourceCamera.d_ptr->m_viewMatrix.copyDataTo(values); - d_ptr->m_viewMatrix = QMatrix4x4(values); - delete[] values; + d_ptr->m_requestedTarget = sourceCamera.d_ptr->m_requestedTarget; d_ptr->m_xRotation = sourceCamera.d_ptr->m_xRotation; d_ptr->m_yRotation = sourceCamera.d_ptr->m_yRotation; @@ -469,6 +471,49 @@ void Q3DCamera::setCameraPosition(float horizontal, float vertical, float zoom) setYRotation(vertical); } +/*! + * \property Q3DCamera::target + * \since QtDataVisualization 1.2 + * + * Holds the camera \a target as a QVector3D. Defaults to \c {QVector3D(0.0, 0.0, 0.0)}. + * + * Valid coordinate values are between \c{-1.0...1.0}, where the edge values indicate + * the edges of the corresponding axis range. Any values outside this range are clamped to the edge. + * + * \note For bar graphs, the Y-coordinate is ignored and camera always targets a point on + * the horizontal background. + */ +QVector3D Q3DCamera::target() const +{ + return d_ptr->m_requestedTarget; +} + +void Q3DCamera::setTarget(const QVector3D &target) +{ + QVector3D newTarget = target; + + if (newTarget.x() < -1.0f) + newTarget.setX(-1.0f); + else if (newTarget.x() > 1.0f) + newTarget.setX(1.0f); + + if (newTarget.y() < -1.0f) + newTarget.setY(-1.0f); + else if (newTarget.y() > 1.0f) + newTarget.setY(1.0f); + + if (newTarget.z() < -1.0f) + newTarget.setZ(-1.0f); + else if (newTarget.z() > 1.0f) + newTarget.setZ(1.0f); + + if (d_ptr->m_requestedTarget != newTarget) { + d_ptr->m_requestedTarget = newTarget; + setDirty(true); + emit targetChanged(newTarget); + } +} + Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) : q_ptr(q), m_isViewMatrixUpdateActive(true), @@ -645,9 +690,9 @@ void Q3DCameraPrivate::updateViewMatrix(float zoomAdjustment) QMatrix4x4 viewMatrix; // Apply to view matrix - viewMatrix.lookAt(q_ptr->position(), m_target, m_up); + viewMatrix.lookAt(q_ptr->position(), m_actualTarget, m_up); // Compensate for translation (if d_ptr->m_target is off origin) - viewMatrix.translate(m_target.x(), m_target.y(), m_target.z()); + viewMatrix.translate(m_actualTarget.x(), m_actualTarget.y(), m_actualTarget.z()); // Apply rotations // Handle x and z rotation when y -angle is other than 0 viewMatrix.rotate(m_xRotation, 0, qCos(qDegreesToRadians(m_yRotation)), @@ -657,7 +702,7 @@ void Q3DCameraPrivate::updateViewMatrix(float zoomAdjustment) // handle zoom by scaling viewMatrix.scale(zoom / 100.0f); // Compensate for translation (if d_ptr->m_target is off origin) - viewMatrix.translate(-m_target.x(), -m_target.y(), -m_target.z()); + viewMatrix.translate(-m_actualTarget.x(), -m_actualTarget.y(), -m_actualTarget.z()); setViewMatrix(viewMatrix); } @@ -713,9 +758,9 @@ void Q3DCameraPrivate::setBaseOrientation(const QVector3D &basePosition, const QVector3D &target, const QVector3D &baseUp) { - if (q_ptr->position() != basePosition || m_target != target || m_up != baseUp) { + if (q_ptr->position() != basePosition || m_actualTarget != target || m_up != baseUp) { q_ptr->setPosition(basePosition); - m_target = target; + m_actualTarget = target; m_up = baseUp; q_ptr->setDirty(true); } diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h index e9ad6dd2..a7da9031 100644 --- a/src/datavisualization/engine/q3dcamera.h +++ b/src/datavisualization/engine/q3dcamera.h @@ -35,6 +35,7 @@ class QT_DATAVISUALIZATION_EXPORT Q3DCamera : public Q3DObject Q_PROPERTY(CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset NOTIFY cameraPresetChanged) Q_PROPERTY(bool wrapXRotation READ wrapXRotation WRITE setWrapXRotation NOTIFY wrapXRotationChanged) Q_PROPERTY(bool wrapYRotation READ wrapYRotation WRITE setWrapYRotation NOTIFY wrapYRotationChanged) + Q_PROPERTY(QVector3D target READ target WRITE setTarget NOTIFY targetChanged REVISION 1) public: enum CameraPreset { @@ -89,6 +90,9 @@ public: void setCameraPosition(float horizontal, float vertical, float zoom = 100.0f); + QVector3D target() const; + void setTarget(const QVector3D &target); + signals: void xRotationChanged(float rotation); void yRotationChanged(float rotation); @@ -96,6 +100,7 @@ signals: void cameraPresetChanged(Q3DCamera::CameraPreset preset); void wrapXRotationChanged(bool isEnabled); void wrapYRotationChanged(bool isEnabled); + Q_REVISION(1) void targetChanged(const QVector3D &target); private: QScopedPointer<Q3DCameraPrivate> d_ptr; diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h index 01e7a508..6e9fd190 100644 --- a/src/datavisualization/engine/q3dcamera_p.h +++ b/src/datavisualization/engine/q3dcamera_p.h @@ -84,7 +84,7 @@ signals: public: Q3DCamera *q_ptr; - QVector3D m_target; + QVector3D m_actualTarget; QVector3D m_up; QMatrix4x4 m_viewMatrix; @@ -100,6 +100,7 @@ public: bool m_wrapXRotation; bool m_wrapYRotation; Q3DCamera::CameraPreset m_activePreset; + QVector3D m_requestedTarget; friend class Bars3DRenderer; friend class Surface3DRenderer; diff --git a/src/datavisualization/engine/q3dlight.cpp b/src/datavisualization/engine/q3dlight.cpp index 03f094cb..92b7bd07 100644 --- a/src/datavisualization/engine/q3dlight.cpp +++ b/src/datavisualization/engine/q3dlight.cpp @@ -68,13 +68,8 @@ Q3DLightPrivate::~Q3DLightPrivate() void Q3DLightPrivate::sync(Q3DLight &other) { - // Copies changed values from this light to the other light. If the other light had same changes, - // those changes are discarded. - if (q_ptr->isDirty()) { - other.copyValuesFrom(*q_ptr); - q_ptr->setDirty(false); - other.setDirty(false); - } + Q_UNUSED(other); + // Do nothing. Only value light has to sync is the position, which we handle internally. } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp index 56edb098..6b442ef8 100644 --- a/src/datavisualization/engine/q3dobject.cpp +++ b/src/datavisualization/engine/q3dobject.cpp @@ -53,9 +53,7 @@ Q3DObject::~Q3DObject() */ void Q3DObject::copyValuesFrom(const Q3DObject &source) { - d_ptr->m_position.setX(source.d_ptr->m_position.x()); - d_ptr->m_position.setY(source.d_ptr->m_position.y()); - d_ptr->m_position.setZ(source.d_ptr->m_position.z()); + d_ptr->m_position = source.d_ptr->m_position; setDirty(true); } @@ -74,6 +72,9 @@ Q3DScene *Q3DObject::parentScene() * \property Q3DObject::position * * This property contains the 3D position of the object. + * + * \note Currently setting this property has no effect, as the positions of Q3DObjects in the + * scene are handled internally. */ QVector3D Q3DObject::position() const { @@ -97,7 +98,7 @@ void Q3DObject::setDirty(bool dirty) { d_ptr->m_isDirty = dirty; if (parentScene()) - parentScene()->d_ptr->m_sceneDirty = true; + parentScene()->d_ptr->markDirty(); } /*! diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp index 9464bc8d..3f2deec0 100644 --- a/src/datavisualization/engine/q3dscene.cpp +++ b/src/datavisualization/engine/q3dscene.cpp @@ -649,4 +649,10 @@ void Q3DScenePrivate::setLightPositionRelativeToCamera(const QVector3D &relative distanceModifier)); } +void Q3DScenePrivate::markDirty() +{ + m_sceneDirty = true; + emit needRender(); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h index 2c69e5e0..c86a0ec1 100644 --- a/src/datavisualization/engine/q3dscene_p.h +++ b/src/datavisualization/engine/q3dscene_p.h @@ -89,6 +89,8 @@ public: float fixedRotation = 0.0f, float distanceModifier = 0.0f); + void markDirty(); + signals: void needRender(); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 5f8eede9..09225b99 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -67,7 +67,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_selectedSeriesCache(0), m_oldSelectedSeriesCache(0), m_dotSizeScale(1.0f), - m_hasHeightAdjustmentChanged(true), m_maxItemSize(0.0f), m_clickedIndex(Scatter3DController::invalidSelectionIndex()), m_havePointSeries(false), @@ -133,6 +132,13 @@ void Scatter3DRenderer::initializeOpenGL() loadBackgroundMesh(); } +void Scatter3DRenderer::fixCameraTarget(QVector3D &target) +{ + target.setX(target.x() * m_scaleX); + target.setY(target.y() * m_scaleY); + target.setZ(target.z() * -m_scaleZ); +} + void Scatter3DRenderer::updateData() { calculateSceneScalingFactors(); @@ -284,13 +290,6 @@ void Scatter3DRenderer::updateScene(Q3DScene *scene) { scene->activeCamera()->d_ptr->setMinYRotation(-90.0f); - if (m_hasHeightAdjustmentChanged) { - // Set initial camera position. Also update if height adjustment has changed. - scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, zeroVector, - upVector); - m_hasHeightAdjustmentChanged = false; - } - Abstract3DRenderer::updateScene(scene); } @@ -2066,6 +2065,9 @@ void Scatter3DRenderer::calculateSceneScalingFactors() m_axisCacheX.setTranslate(-m_scaleX); m_axisCacheY.setTranslate(-m_scaleY); m_axisCacheZ.setTranslate(m_scaleZ); + + updateCameraViewport(); + updateCustomItemPositions(); } void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader) @@ -2252,7 +2254,7 @@ QVector3D Scatter3DRenderer::convertPositionToTranslation(const QVector3D &posit } else { xTrans = position.x() * m_scaleX; yTrans = position.y() * m_scaleY; - zTrans = position.z() * m_scaleZ; + zTrans = position.z() * -m_scaleZ; } return QVector3D(xTrans, yTrans, zTrans); } diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 9baad16a..5f82bf70 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -77,7 +77,6 @@ private: ScatterSeriesRenderCache *m_selectedSeriesCache; ScatterSeriesRenderCache *m_oldSelectedSeriesCache; GLfloat m_dotSizeScale; - bool m_hasHeightAdjustmentChanged; ScatterRenderItem m_dummyRenderItem; GLfloat m_maxItemSize; int m_clickedIndex; @@ -112,6 +111,7 @@ public slots: protected: virtual void initializeOpenGL(); + virtual void fixCameraTarget(QVector3D &target); private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 83b5c7fb..1607f66a 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -66,7 +66,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_flatSupported(true), m_selectionActive(false), m_shadowQualityMultiplier(3), - m_hasHeightAdjustmentChanged(true), m_selectedPoint(Surface3DController::invalidSelectionPosition()), m_selectedSeries(0), m_clickedPosition(Surface3DController::invalidSelectionPosition()), @@ -152,6 +151,13 @@ void Surface3DRenderer::initializeOpenGL() m_noShadowTexture = m_textureHelper->create2DTexture(image, false, true, false, true); } +void Surface3DRenderer::fixCameraTarget(QVector3D &target) +{ + target.setX(target.x() * m_scaleX); + target.setY(target.y() * m_scaleY); + target.setZ(target.z() * -m_scaleZ); +} + void Surface3DRenderer::updateData() { calculateSceneScalingFactors(); @@ -693,15 +699,6 @@ QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array) void Surface3DRenderer::updateScene(Q3DScene *scene) { - // Set initial camera position - // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later - if (m_hasHeightAdjustmentChanged) { - scene->activeCamera()->d_ptr->setBaseOrientation(cameraDistanceVector, zeroVector, - upVector); - // For now this is used just to make things once. Proper use will come - m_hasHeightAdjustmentChanged = false; - } - Abstract3DRenderer::updateScene(scene); if (m_selectionActive @@ -1111,7 +1108,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) / activeCamera->zoomLevel() / m_autoScaleAdjustment * 100.0f; qreal cameraAngle = qreal(activeCamera->yRotation()) / 180.0 * M_PI; float cameraYPos = float(qSin(cameraAngle)) * distanceToCenter; - m_yFlippedForGrid = cameraYPos < (m_scaleYWithBackground); + m_yFlippedForGrid = cameraYPos < (m_scaleYWithBackground - m_oldCameraTarget.y()); } else if (m_useOrthoProjection && activeCamera->yRotation() == 0.0f) { // With ortho we only need to flip at angle zero, to fix label autorotation angles m_yFlippedForGrid = !m_yFlipped; @@ -2517,6 +2514,9 @@ void Surface3DRenderer::calculateSceneScalingFactors() m_axisCacheX.setTranslate(-m_scaleX); m_axisCacheY.setTranslate(-m_scaleY); m_axisCacheZ.setTranslate(m_scaleZ); + + updateCameraViewport(); + updateCustomItemPositions(); } void Surface3DRenderer::checkFlatSupport(SurfaceSeriesRenderCache *cache) @@ -2962,7 +2962,7 @@ QVector3D Surface3DRenderer::convertPositionToTranslation(const QVector3D &posit } else { xTrans = position.x() * m_scaleX; yTrans = position.y() * m_scaleY; - zTrans = position.z() * m_scaleZ; + zTrans = position.z() * -m_scaleZ; } return QVector3D(xTrans, yTrans, zTrans); } diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index f34a927a..9c53757d 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -75,7 +75,6 @@ private: bool m_selectionActive; AbstractRenderItem m_dummyRenderItem; GLint m_shadowQualityMultiplier; - bool m_hasHeightAdjustmentChanged; QPoint m_selectedPoint; QSurface3DSeries *m_selectedSeries; QPoint m_clickedPosition; @@ -111,6 +110,7 @@ public: protected: void initializeOpenGL(); + virtual void fixCameraTarget(QVector3D &target); signals: void flatShadingSupportedChanged(bool supported); |