diff options
27 files changed, 434 insertions, 190 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); diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp index c824afec..f5e2b4e0 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp @@ -114,6 +114,7 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri) qmlRegisterUncreatableType<AbstractDeclarative, 2>(uri, 1, 2, "AbstractGraph3D", QLatin1String("Trying to create uncreatable: AbstractGraph3D.")); qmlRegisterType<DeclarativeSurface, 1>(uri, 1, 2, "Surface3D"); + qmlRegisterType<Q3DCamera, 1>(uri, 1, 2, "Camera3D"); // New types qmlRegisterType<Q3DInputHandler>(uri, 1, 2, "InputHandler3D"); diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp index e0f9ff18..445c235e 100644 --- a/tests/barstest/chart.cpp +++ b/tests/barstest/chart.cpp @@ -1495,6 +1495,30 @@ void GraphModifier::handleFpsChange(qreal fps) m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps))); } +void GraphModifier::setCameraTargetX(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setX(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void GraphModifier::setCameraTargetY(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setY(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void GraphModifier::setCameraTargetZ(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setZ(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + void GraphModifier::populateFlatSeries(QBar3DSeries *series, int rows, int columns, float value) { QBarDataArray *dataArray = new QBarDataArray; diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h index 7ee781ad..6740df73 100644 --- a/tests/barstest/chart.h +++ b/tests/barstest/chart.h @@ -118,6 +118,9 @@ public slots: void triggerRotation(); void handleValueAxisLabelsChanged(); void handleFpsChange(qreal fps); + void setCameraTargetX(int value); + void setCameraTargetY(int value); + void setCameraTargetZ(int value); signals: void shadowQualityChanged(int quality); @@ -172,6 +175,7 @@ private: QTimer m_rotationTimer; QLabel *m_fpsLabel; QBar3DSeries *m_extraSeries; + QVector3D m_cameraTarget; }; #endif diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp index 2d755c7f..bd891cd3 100644 --- a/tests/barstest/main.cpp +++ b/tests/barstest/main.cpp @@ -331,6 +331,22 @@ int main(int argc, char **argv) valueAxisSegmentsSpin->setMaximum(100); valueAxisSegmentsSpin->setValue(10); + QSlider *cameraTargetSliderX = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderX->setTickInterval(1); + cameraTargetSliderX->setMinimum(-100); + cameraTargetSliderX->setValue(0); + cameraTargetSliderX->setMaximum(100); + QSlider *cameraTargetSliderY = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderY->setTickInterval(1); + cameraTargetSliderY->setMinimum(-100); + cameraTargetSliderY->setValue(0); + cameraTargetSliderY->setMaximum(100); + QSlider *cameraTargetSliderZ = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderZ->setTickInterval(1); + cameraTargetSliderZ->setMinimum(-100); + cameraTargetSliderZ->setValue(0); + cameraTargetSliderZ->setMaximum(100); + vLayout->addWidget(addSeriesButton, 0, Qt::AlignTop); vLayout->addWidget(addDataButton, 0, Qt::AlignTop); vLayout->addWidget(addMultiDataButton, 0, Qt::AlignTop); @@ -400,7 +416,11 @@ int main(int argc, char **argv) vLayout3->addWidget(new QLabel(QStringLiteral("Log axis base")), 0, Qt::AlignTop); vLayout3->addWidget(logBaseEdit, 0, Qt::AlignTop); vLayout3->addWidget(new QLabel(QStringLiteral("Value axis segments")), 0, Qt::AlignTop); - vLayout3->addWidget(valueAxisSegmentsSpin, 1, Qt::AlignTop); + vLayout3->addWidget(valueAxisSegmentsSpin, 0, Qt::AlignTop); + vLayout3->addWidget(new QLabel(QStringLiteral("Camera target")), 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderX, 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderY, 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderZ, 1, Qt::AlignTop); // TODO: Add example for setMeshFileName widget->show(); @@ -429,6 +449,12 @@ int main(int argc, char **argv) &GraphModifier::setMinY); QObject::connect(maxSliderY, &QSlider::valueChanged, modifier, &GraphModifier::setMaxY); + QObject::connect(cameraTargetSliderX, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetX); + QObject::connect(cameraTargetSliderY, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetY); + QObject::connect(cameraTargetSliderZ, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetZ); QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier, SLOT(changeShadowQuality(int))); diff --git a/tests/qmlcamera/qml/qmlcamera/main.qml b/tests/qmlcamera/qml/qmlcamera/main.qml index 444e175c..cb1737f6 100644 --- a/tests/qmlcamera/qml/qmlcamera/main.qml +++ b/tests/qmlcamera/qml/qmlcamera/main.qml @@ -18,7 +18,7 @@ import QtQuick 2.1 import QtQuick.Controls 1.0 -import QtDataVisualization 1.1 +import QtDataVisualization 1.2 import "." Rectangle { @@ -35,6 +35,15 @@ Rectangle { id: chartAxes } + Camera3D { + id: customCamera + wrapXRotation: false + xRotation: camControlArea.xValue + yRotation: camControlArea.yValue + zoomLevel: zoomSlider.value + target: Qt.vector3d(1.0, 1.0, 1.0) + } + Item { id: dataView width: parent.width - camControlArea.width @@ -60,21 +69,18 @@ Rectangle { columnAxis: chartAxes.column valueAxis: chartAxes.expenses - // Bind UI controls to the camera - scene.activeCamera.wrapXRotation: false - scene.activeCamera.xRotation: camControlArea.xValue - scene.activeCamera.yRotation: camControlArea.yValue - scene.activeCamera.zoomLevel: zoomSlider.value + scene.activeCamera: customCamera inputHandler: null customItemList: [shuttleItem, labelItem] + orthoProjection: true } Custom3DItem { id: shuttleItem meshFile: ":/items/shuttle.obj" textureFile: ":/items/shuttle.png" - position: Qt.vector3d(5.0,29.0,3.0) + position: Qt.vector3d(2.0,29.0,2.0) scaling: Qt.vector3d(0.2,0.2,0.2) } @@ -82,7 +88,7 @@ Rectangle { id: labelItem facingCamera: true positionAbsolute: true - position: Qt.vector3d(0.0,1.5,0.0) + position: Qt.vector3d(-1.0,1.5,-1.0) scaling: Qt.vector3d(1.0,1.0,1.0) text: "Qt Shuttle" } @@ -162,6 +168,11 @@ Rectangle { currentAngle += 5 chartData.series.meshAngle = currentAngle shuttleItem.setRotationAxisAndAngle(Qt.vector3d(0.0, 1.0, 1.0), currentAngle) + console.log("label pos:", labelItem.position) + labelItem.position.x += 0.1 + labelItem.position.z += 0.1 + customCamera.target.x -= 0.1 + customCamera.target.z -= 0.1 } } diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp index 55515cb0..116a4dc2 100644 --- a/tests/scattertest/main.cpp +++ b/tests/scattertest/main.cpp @@ -41,6 +41,7 @@ int main(int argc, char **argv) QHBoxLayout *hLayout = new QHBoxLayout(widget); QVBoxLayout *vLayout = new QVBoxLayout(); QVBoxLayout *vLayout2 = new QVBoxLayout(); + QVBoxLayout *vLayout3 = new QVBoxLayout(); Q3DScatter *chart = new Q3DScatter(); QSize screenSize = chart->screen()->size(); @@ -56,6 +57,7 @@ int main(int argc, char **argv) hLayout->addWidget(container, 1); hLayout->addLayout(vLayout); hLayout->addLayout(vLayout2); + hLayout->addLayout(vLayout3); QPushButton *themeButton = new QPushButton(widget); themeButton->setText(QStringLiteral("Change theme")); @@ -276,6 +278,22 @@ int main(int argc, char **argv) radialLabelSlider->setValue(100); radialLabelSlider->setMaximum(150); + QSlider *cameraTargetSliderX = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderX->setTickInterval(1); + cameraTargetSliderX->setMinimum(-100); + cameraTargetSliderX->setValue(0); + cameraTargetSliderX->setMaximum(100); + QSlider *cameraTargetSliderY = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderY->setTickInterval(1); + cameraTargetSliderY->setMinimum(-100); + cameraTargetSliderY->setValue(0); + cameraTargetSliderY->setMaximum(100); + QSlider *cameraTargetSliderZ = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderZ->setTickInterval(1); + cameraTargetSliderZ->setMinimum(-100); + cameraTargetSliderZ->setValue(0); + cameraTargetSliderZ->setMaximum(100); + vLayout->addWidget(themeButton, 0, Qt::AlignTop); vLayout->addWidget(labelButton, 0, Qt::AlignTop); vLayout->addWidget(styleButton, 0, Qt::AlignTop); @@ -326,15 +344,20 @@ int main(int argc, char **argv) vLayout2->addWidget(aspectRatioSlider); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust horizontal aspect ratio"))); vLayout2->addWidget(horizontalAspectRatioSlider, 1, Qt::AlignTop); - vLayout2->addWidget(optimizationStaticCB); - vLayout2->addWidget(orthoCB); - vLayout2->addWidget(polarCB); - vLayout2->addWidget(axisTitlesVisibleCB); - vLayout2->addWidget(axisTitlesFixedCB); - vLayout2->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); - vLayout2->addWidget(axisLabelRotationSlider); - vLayout2->addWidget(new QLabel(QStringLiteral("Radial label offset"))); - vLayout2->addWidget(radialLabelSlider, 1, Qt::AlignTop); + + vLayout3->addWidget(optimizationStaticCB); + vLayout3->addWidget(orthoCB); + vLayout3->addWidget(polarCB); + vLayout3->addWidget(axisTitlesVisibleCB); + vLayout3->addWidget(axisTitlesFixedCB); + vLayout3->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); + vLayout3->addWidget(axisLabelRotationSlider); + vLayout3->addWidget(new QLabel(QStringLiteral("Radial label offset"))); + vLayout3->addWidget(radialLabelSlider, 0, Qt::AlignTop); + vLayout3->addWidget(new QLabel(QStringLiteral("Camera target")), 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderX, 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderY, 0, Qt::AlignTop); + vLayout3->addWidget(cameraTargetSliderZ, 1, Qt::AlignTop); ScatterDataModifier *modifier = new ScatterDataModifier(chart); @@ -440,6 +463,12 @@ int main(int argc, char **argv) &ScatterDataModifier::setHorizontalAspectRatio); QObject::connect(radialLabelSlider, &QSlider::valueChanged, modifier, &ScatterDataModifier::changeRadialLabelOffset); + QObject::connect(cameraTargetSliderX, &QSlider::valueChanged, modifier, + &ScatterDataModifier::setCameraTargetX); + QObject::connect(cameraTargetSliderY, &QSlider::valueChanged, modifier, + &ScatterDataModifier::setCameraTargetY); + QObject::connect(cameraTargetSliderZ, &QSlider::valueChanged, modifier, + &ScatterDataModifier::setCameraTargetZ); modifier->setFpsLabel(fpsLabel); diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index 5db772b5..35d56236 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -993,6 +993,30 @@ void ScatterDataModifier::toggleOrtho(bool enable) m_chart->setOrthoProjection(enable); } +void ScatterDataModifier::setCameraTargetX(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setX(float(value) / 100.0f); + m_chart->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void ScatterDataModifier::setCameraTargetY(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setY(float(value) / 100.0f); + m_chart->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void ScatterDataModifier::setCameraTargetZ(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setZ(float(value) / 100.0f); + m_chart->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + void ScatterDataModifier::changeShadowQuality(int quality) { QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality); diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h index df2494b6..1a97c5f0 100644 --- a/tests/scattertest/scatterchart.h +++ b/tests/scattertest/scatterchart.h @@ -98,6 +98,9 @@ public slots: void togglePolar(bool enable); void toggleStatic(bool enable); void toggleOrtho(bool enable); + void setCameraTargetX(int value); + void setCameraTargetY(int value); + void setCameraTargetZ(int value); signals: void shadowQualityChanged(int quality); @@ -118,6 +121,8 @@ private: QScatter3DSeries *m_targetSeries; QScatterDataArray m_massiveTestCacheArray; QLabel *m_fpsLabel; + QVector3D m_cameraTarget; + }; #endif diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp index a685b71b..a22ede2b 100644 --- a/tests/surfacetest/graphmodifier.cpp +++ b/tests/surfacetest/graphmodifier.cpp @@ -793,6 +793,30 @@ void GraphModifier::togglePolar(bool enabled) m_graph->setPolar(enabled); } +void GraphModifier::setCameraTargetX(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setX(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void GraphModifier::setCameraTargetY(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setY(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + +void GraphModifier::setCameraTargetZ(int value) +{ + // Value is (-100, 100), normalize + m_cameraTarget.setZ(float(value) / 100.0f); + m_graph->scene()->activeCamera()->setTarget(m_cameraTarget); + qDebug() << "m_cameraTarget:" << m_cameraTarget; +} + void GraphModifier::resetArrayAndSliders(QSurfaceDataArray *array, float minZ, float maxZ, float minX, float maxX) { m_axisMinSliderX->setValue(minX); diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h index 62145d45..f461f022 100644 --- a/tests/surfacetest/graphmodifier.h +++ b/tests/surfacetest/graphmodifier.h @@ -133,6 +133,9 @@ public slots: void toggleXAscending(bool enabled); void toggleZAscending(bool enabled); void togglePolar(bool enabled); + void setCameraTargetX(int value); + void setCameraTargetY(int value); + void setCameraTargetZ(int value); private: void fillSeries(); @@ -186,6 +189,7 @@ private: float m_multiSampleOffsetX[4]; float m_multiSampleOffsetZ[4]; QSurfaceDataArray m_massiveTestCacheArray; + QVector3D m_cameraTarget; }; #endif diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp index 3a7307ea..f89e6c50 100644 --- a/tests/surfacetest/main.cpp +++ b/tests/surfacetest/main.cpp @@ -46,8 +46,10 @@ int main(int argc, char *argv[]) QHBoxLayout *hLayout = new QHBoxLayout(widget); QVBoxLayout *vLayout = new QVBoxLayout(); QVBoxLayout *vLayout2 = new QVBoxLayout(); + QVBoxLayout *vLayout3 = new QVBoxLayout(); vLayout->setAlignment(Qt::AlignTop); vLayout2->setAlignment(Qt::AlignTop); + vLayout3->setAlignment(Qt::AlignTop); Q3DSurface *surfaceGraph = new Q3DSurface(); QSize screenSize = surfaceGraph->screen()->size(); @@ -66,6 +68,7 @@ int main(int argc, char *argv[]) hLayout->addWidget(container, 1); hLayout->addLayout(vLayout); hLayout->addLayout(vLayout2); + hLayout->addLayout(vLayout3); QCheckBox *smoothCB = new QCheckBox(widget); smoothCB->setText(QStringLiteral("Flat Surface")); @@ -406,6 +409,22 @@ int main(int argc, char *argv[]) surfaceTextureCB->setText(QStringLiteral("Map texture")); surfaceTextureCB->setChecked(false); + QSlider *cameraTargetSliderX = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderX->setTickInterval(1); + cameraTargetSliderX->setMinimum(-100); + cameraTargetSliderX->setValue(0); + cameraTargetSliderX->setMaximum(100); + QSlider *cameraTargetSliderY = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderY->setTickInterval(1); + cameraTargetSliderY->setMinimum(-100); + cameraTargetSliderY->setValue(0); + cameraTargetSliderY->setMaximum(100); + QSlider *cameraTargetSliderZ = new QSlider(Qt::Horizontal, widget); + cameraTargetSliderZ->setTickInterval(1); + cameraTargetSliderZ->setMinimum(-100); + cameraTargetSliderZ->setValue(0); + cameraTargetSliderZ->setMaximum(100); + // Add controls to the layout #ifdef MULTI_SERIES vLayout->addWidget(series1CB); @@ -433,7 +452,7 @@ int main(int argc, char *argv[]) vLayout->addWidget(surfaceGridS4CB); vLayout->addWidget(surfaceS4CB); vLayout->addWidget(series4VisibleCB); - vLayout->addWidget(surfaceTextureCB); + vLayout->addWidget(surfaceTextureCB, 1, Qt::AlignTop); #endif #ifndef MULTI_SERIES vLayout->addWidget(new QLabel(QStringLiteral("Select surface sample"))); @@ -443,59 +462,65 @@ int main(int argc, char *argv[]) vLayout->addWidget(new QLabel(QStringLiteral("Adjust sample count"))); vLayout->addWidget(gridSlidersLockCB); vLayout->addWidget(gridSliderX); - vLayout->addWidget(gridSliderZ); + vLayout->addWidget(gridSliderZ, 1, Qt::AlignTop); #endif - vLayout->addWidget(new QLabel(QStringLiteral("Adjust vertical aspect ratio"))); - vLayout->addWidget(aspectRatioSlider); - vLayout->addWidget(new QLabel(QStringLiteral("Adjust horizontal aspect ratio"))); - vLayout->addWidget(horizontalAspectRatioSlider); - vLayout->addWidget(new QLabel(QStringLiteral("Adjust axis range"))); - vLayout->addWidget(axisRangeSliderX); - vLayout->addWidget(axisRangeSliderY); - vLayout->addWidget(axisRangeSliderZ); - vLayout->addWidget(new QLabel(QStringLiteral("Adjust axis minimum"))); - vLayout->addWidget(axisMinSliderX); - vLayout->addWidget(axisMinSliderY); - vLayout->addWidget(axisMinSliderZ); - vLayout->addWidget(xAscendingCB); - vLayout->addWidget(zAscendingCB); - vLayout->addWidget(polarCB); + + vLayout2->addWidget(new QLabel(QStringLiteral("Adjust vertical aspect ratio"))); + vLayout2->addWidget(aspectRatioSlider); + vLayout2->addWidget(new QLabel(QStringLiteral("Adjust horizontal aspect ratio"))); + vLayout2->addWidget(horizontalAspectRatioSlider); + vLayout2->addWidget(new QLabel(QStringLiteral("Adjust axis range"))); + vLayout2->addWidget(axisRangeSliderX); + vLayout2->addWidget(axisRangeSliderY); + vLayout2->addWidget(axisRangeSliderZ); + vLayout2->addWidget(new QLabel(QStringLiteral("Adjust axis minimum"))); + vLayout2->addWidget(axisMinSliderX); + vLayout2->addWidget(axisMinSliderY); + vLayout2->addWidget(axisMinSliderZ); + vLayout2->addWidget(xAscendingCB); + vLayout2->addWidget(zAscendingCB); + vLayout2->addWidget(polarCB); vLayout2->addWidget(new QLabel(QStringLiteral("Change font"))); vLayout2->addWidget(fontList); - vLayout2->addWidget(labelButton); - vLayout2->addWidget(meshButton); vLayout2->addWidget(new QLabel(QStringLiteral("Change theme"))); vLayout2->addWidget(themeList); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality"))); vLayout2->addWidget(shadowQuality); vLayout2->addWidget(new QLabel(QStringLiteral("Selection Mode"))); vLayout2->addWidget(selectionMode); + vLayout2->addWidget(new QLabel(QStringLiteral("Camera target"))); + vLayout2->addWidget(cameraTargetSliderX); + vLayout2->addWidget(cameraTargetSliderY); + vLayout2->addWidget(cameraTargetSliderZ, 1, Qt::AlignTop); + + vLayout3->addWidget(labelButton); + vLayout3->addWidget(meshButton); #ifndef MULTI_SERIES - vLayout2->addWidget(selectButton); - vLayout2->addWidget(selectionInfoLabel); - vLayout2->addWidget(flipViewsButton); + vLayout3->addWidget(selectButton); + vLayout3->addWidget(selectionInfoLabel); + vLayout3->addWidget(flipViewsButton); #endif - vLayout2->addWidget(colorPB); - vLayout2->addWidget(changeRowButton); - vLayout2->addWidget(changeRowsButton); - vLayout2->addWidget(changeMultipleRowsButton); - vLayout2->addWidget(changeItemButton); - vLayout2->addWidget(changeMultipleItemButton); - vLayout2->addWidget(addRowButton); - vLayout2->addWidget(addRowsButton); - vLayout2->addWidget(insertRowButton); - vLayout2->addWidget(insertRowsButton); - vLayout2->addWidget(removeRowButton); - vLayout2->addWidget(resetArrayButton); - vLayout2->addWidget(resetArrayEmptyButton); - vLayout2->addWidget(massiveDataTestButton); - vLayout2->addWidget(testReverseButton); - vLayout2->addWidget(testDataOrderingButton); - vLayout2->addWidget(axisTitlesVisibleCB); - vLayout2->addWidget(axisTitlesFixedCB); - vLayout2->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); - vLayout2->addWidget(axisLabelRotationSlider, 1, Qt::AlignTop); + vLayout3->addWidget(colorPB); + vLayout3->addWidget(changeRowButton); + vLayout3->addWidget(changeRowsButton); + vLayout3->addWidget(changeMultipleRowsButton); + vLayout3->addWidget(changeItemButton); + vLayout3->addWidget(changeMultipleItemButton); + vLayout3->addWidget(addRowButton); + vLayout3->addWidget(addRowsButton); + vLayout3->addWidget(insertRowButton); + vLayout3->addWidget(insertRowsButton); + vLayout3->addWidget(removeRowButton); + vLayout3->addWidget(resetArrayButton); + vLayout3->addWidget(resetArrayEmptyButton); + vLayout3->addWidget(massiveDataTestButton); + vLayout3->addWidget(testReverseButton); + vLayout3->addWidget(testDataOrderingButton); + vLayout3->addWidget(axisTitlesVisibleCB); + vLayout3->addWidget(axisTitlesFixedCB); + vLayout3->addWidget(new QLabel(QStringLiteral("Axis label rotation"))); + vLayout3->addWidget(axisLabelRotationSlider, 1, Qt::AlignTop); widget->show(); @@ -676,6 +701,12 @@ int main(int argc, char *argv[]) modifier, &GraphModifier::setHorizontalAspectRatio); QObject::connect(surfaceTextureCB, &QCheckBox::stateChanged, modifier, &GraphModifier::setSurfaceTexture); + QObject::connect(cameraTargetSliderX, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetX); + QObject::connect(cameraTargetSliderY, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetY); + QObject::connect(cameraTargetSliderZ, &QSlider::valueChanged, modifier, + &GraphModifier::setCameraTargetZ); #ifdef MULTI_SERIES modifier->setSeries1CB(series1CB); |