diff options
Diffstat (limited to 'src/datavisualization/engine')
68 files changed, 3579 insertions, 2259 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 9835dbe4..4989ddb5 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -18,9 +18,9 @@ #include "abstract3dcontroller_p.h" #include "camerahelper_p.h" -#include "q3dabstractaxis_p.h" -#include "q3dvalueaxis.h" -#include "q3dcategoryaxis.h" +#include "qabstract3daxis_p.h" +#include "qvalue3daxis.h" +#include "qcategory3daxis.h" #include "abstract3drenderer_p.h" #include "q3dcamera.h" #include "q3dlight.h" @@ -29,18 +29,21 @@ #include "qtouch3dinputhandler.h" #include "qabstract3dseries_p.h" #include "thememanager_p.h" +#include "q3dtheme_p.h" #include "q3dscene_p.h" +#include "q3dscene.h" #include <QThread> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -Abstract3DController::Abstract3DController(QRect initialViewport, QObject *parent) : +Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scene, + QObject *parent) : QObject(parent), m_themeManager(new ThemeManager(this)), - m_selectionMode(QDataVis::SelectionItem), - m_shadowQuality(QDataVis::ShadowQualityMedium), - m_scene(new Q3DScene()), + m_selectionMode(QAbstract3DGraph::SelectionItem), + m_shadowQuality(QAbstract3DGraph::ShadowQualityMedium), + m_scene(scene), m_activeInputHandler(0), m_axisX(0), m_axisY(0), @@ -51,8 +54,13 @@ Abstract3DController::Abstract3DController(QRect initialViewport, QObject *paren m_isSeriesVisualsDirty(true), m_renderPending(false) { + if (!m_scene) + m_scene = new Q3DScene; + // Set initial theme - setTheme(new Q3DTheme(Q3DTheme::ThemeQt)); + Q3DTheme *defaultTheme = new Q3DTheme(Q3DTheme::ThemeQt); + defaultTheme->d_ptr->setDefaultTheme(true); + setActiveTheme(defaultTheme); m_scene->d_ptr->setViewport(initialViewport); @@ -64,8 +72,8 @@ Abstract3DController::Abstract3DController(QRect initialViewport, QObject *paren inputHandler = new QTouch3DInputHandler(); inputHandler->d_ptr->m_isDefaultHandler = true; setActiveInputHandler(inputHandler); - connect(inputHandler, &QAbstract3DInputHandler::inputStateChanged, this, - &Abstract3DController::handleInputStateChanged); + connect(inputHandler, &QAbstract3DInputHandler::inputViewChanged, this, + &Abstract3DController::handleInputViewChanged); connect(inputHandler, &QAbstract3DInputHandler::positionChanged, this, &Abstract3DController::handleInputPositionChanged); connect(m_scene->d_ptr.data(), &Q3DScenePrivate::needRender, this, @@ -94,15 +102,30 @@ void Abstract3DController::setRenderer(Abstract3DRenderer *renderer) void Abstract3DController::addSeries(QAbstract3DSeries *series) { - if (series && !m_seriesList.contains(series)) { - int oldSize = m_seriesList.size(); - m_seriesList.append(series); - series->d_ptr->setController(this); - QObject::connect(series, &QAbstract3DSeries::visibilityChanged, - this, &Abstract3DController::handleSeriesVisibilityChanged); + insertSeries(m_seriesList.size(), series); +} + +void Abstract3DController::insertSeries(int index, QAbstract3DSeries *series) +{ + if (series) { + if (m_seriesList.contains(series)) { + int oldIndex = m_seriesList.indexOf(series); + if (index != oldIndex) { + m_seriesList.removeOne(series); + if (oldIndex < index) + index--; + m_seriesList.insert(index, series); + } + } else { + int oldSize = m_seriesList.size(); + m_seriesList.insert(index, series); + series->d_ptr->setController(this); + QObject::connect(series, &QAbstract3DSeries::visibilityChanged, + this, &Abstract3DController::handleSeriesVisibilityChanged); + series->d_ptr->resetToTheme(*m_themeManager->activeTheme(), oldSize, false); + } if (series->isVisible()) handleSeriesVisibilityChangedBySender(series); - series->d_ptr->resetToTheme(*m_themeManager->theme(), oldSize, false); } } @@ -129,13 +152,20 @@ QList<QAbstract3DSeries *> Abstract3DController::seriesList() */ void Abstract3DController::synchDataToRenderer() { - // If we don't have a renderer, don't do anything - if (!m_renderer) - return; + // Subclass implementations check for renderer validity already, so no need to check here. + + // If there is a pending click from renderer, handle that first. + if (m_renderer->isClickPending()) { + handlePendingClick(); + m_renderer->clearClickPending(); + } + + startRecordingRemovesAndInserts(); - m_renderer->updateScene(m_scene); + if (m_scene->d_ptr->m_sceneDirty) + m_renderer->updateScene(m_scene); - m_renderer->updateTheme(m_themeManager->theme()); + m_renderer->updateTheme(m_themeManager->activeTheme()); if (m_changeTracker.shadowQualityChanged) { m_renderer->updateShadowQuality(m_shadowQuality); @@ -148,144 +178,144 @@ void Abstract3DController::synchDataToRenderer() } if (m_changeTracker.axisXTypeChanged) { - m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationX, m_axisX->type()); + m_renderer->updateAxisType(QAbstract3DAxis::AxisOrientationX, m_axisX->type()); m_changeTracker.axisXTypeChanged = false; } if (m_changeTracker.axisYTypeChanged) { - m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationY, m_axisY->type()); + m_renderer->updateAxisType(QAbstract3DAxis::AxisOrientationY, m_axisY->type()); m_changeTracker.axisYTypeChanged = false; } if (m_changeTracker.axisZTypeChanged) { - m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->type()); + m_renderer->updateAxisType(QAbstract3DAxis::AxisOrientationZ, m_axisZ->type()); m_changeTracker.axisZTypeChanged = false; } if (m_changeTracker.axisXTitleChanged) { - m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationX, m_axisX->title()); + m_renderer->updateAxisTitle(QAbstract3DAxis::AxisOrientationX, m_axisX->title()); m_changeTracker.axisXTitleChanged = false; } if (m_changeTracker.axisYTitleChanged) { - m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationY, m_axisY->title()); + m_renderer->updateAxisTitle(QAbstract3DAxis::AxisOrientationY, m_axisY->title()); m_changeTracker.axisYTitleChanged = false; } if (m_changeTracker.axisZTitleChanged) { - m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->title()); + m_renderer->updateAxisTitle(QAbstract3DAxis::AxisOrientationZ, m_axisZ->title()); m_changeTracker.axisZTitleChanged = false; } if (m_changeTracker.axisXLabelsChanged) { - m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationX, m_axisX->labels()); + m_renderer->updateAxisLabels(QAbstract3DAxis::AxisOrientationX, m_axisX->labels()); m_changeTracker.axisXLabelsChanged = false; } if (m_changeTracker.axisYLabelsChanged) { - m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationY, m_axisY->labels()); + m_renderer->updateAxisLabels(QAbstract3DAxis::AxisOrientationY, m_axisY->labels()); m_changeTracker.axisYLabelsChanged = false; } if (m_changeTracker.axisZLabelsChanged) { - m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->labels()); + m_renderer->updateAxisLabels(QAbstract3DAxis::AxisOrientationZ, m_axisZ->labels()); m_changeTracker.axisZLabelsChanged = false; } if (m_changeTracker.axisXRangeChanged) { - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationX, m_axisX->min(), + m_renderer->updateAxisRange(QAbstract3DAxis::AxisOrientationX, m_axisX->min(), m_axisX->max()); m_changeTracker.axisXRangeChanged = false; } if (m_changeTracker.axisYRangeChanged) { - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationY, m_axisY->min(), + m_renderer->updateAxisRange(QAbstract3DAxis::AxisOrientationY, m_axisY->min(), m_axisY->max()); m_changeTracker.axisYRangeChanged = false; } if (m_changeTracker.axisZRangeChanged) { - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->min(), + m_renderer->updateAxisRange(QAbstract3DAxis::AxisOrientationZ, m_axisZ->min(), m_axisZ->max()); m_changeTracker.axisZRangeChanged = false; } if (m_changeTracker.axisXSegmentCountChanged) { m_changeTracker.axisXSegmentCountChanged = false; - if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationX, + if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX); + m_renderer->updateAxisSegmentCount(QAbstract3DAxis::AxisOrientationX, valueAxisX->segmentCount()); } } if (m_changeTracker.axisYSegmentCountChanged) { m_changeTracker.axisYSegmentCountChanged = false; - if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationY, + if (m_axisY->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY); + m_renderer->updateAxisSegmentCount(QAbstract3DAxis::AxisOrientationY, valueAxisY->segmentCount()); } } if (m_changeTracker.axisZSegmentCountChanged) { m_changeTracker.axisZSegmentCountChanged = false; - if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); - m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationZ, + if (m_axisZ->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisZ = static_cast<QValue3DAxis *>(m_axisZ); + m_renderer->updateAxisSegmentCount(QAbstract3DAxis::AxisOrientationZ, valueAxisZ->segmentCount()); } } if (m_changeTracker.axisXSubSegmentCountChanged) { m_changeTracker.axisXSubSegmentCountChanged = false; - if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationX, + if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX); + m_renderer->updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientationX, valueAxisX->subSegmentCount()); } } if (m_changeTracker.axisYSubSegmentCountChanged) { m_changeTracker.axisYSubSegmentCountChanged = false; - if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationY, + if (m_axisY->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY); + m_renderer->updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientationY, valueAxisY->subSegmentCount()); } } if (m_changeTracker.axisZSubSegmentCountChanged) { m_changeTracker.axisZSubSegmentCountChanged = false; - if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); - m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationZ, + if (m_axisZ->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisZ = static_cast<QValue3DAxis *>(m_axisZ); + m_renderer->updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientationZ, valueAxisZ->subSegmentCount()); } } if (m_changeTracker.axisXLabelFormatChanged) { m_changeTracker.axisXLabelFormatChanged = false; - if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationX, + if (m_axisX->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX); + m_renderer->updateAxisLabelFormat(QAbstract3DAxis::AxisOrientationX, valueAxisX->labelFormat()); } } if (m_changeTracker.axisYLabelFormatChanged) { m_changeTracker.axisYLabelFormatChanged = false; - if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationY, + if (m_axisY->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY); + m_renderer->updateAxisLabelFormat(QAbstract3DAxis::AxisOrientationY, valueAxisY->labelFormat()); } } if (m_changeTracker.axisZLabelFormatChanged) { m_changeTracker.axisZLabelFormatChanged = false; - if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); - m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationZ, + if (m_axisZ->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxisZ = static_cast<QValue3DAxis *>(m_axisZ); + m_renderer->updateAxisLabelFormat(QAbstract3DAxis::AxisOrientationZ, valueAxisZ->labelFormat()); } } @@ -446,37 +476,62 @@ void Abstract3DController::handleThemeMultiHighlightGradientChanged(const QLinea markSeriesVisualsDirty(); } -void Abstract3DController::setAxisX(Q3DAbstractAxis *axis) +void Abstract3DController::handleThemeTypeChanged(Q3DTheme::Theme theme) { - setAxisHelper(Q3DAbstractAxis::AxisOrientationX, axis, &m_axisX); + Q_UNUSED(theme) + + // Changing theme type is logically equivalent of changing the entire theme + // object, so reset all attached series to the new theme. + + Q3DTheme *activeTheme = m_themeManager->activeTheme(); + for (int i = 0; i < m_seriesList.size(); i++) + m_seriesList.at(i)->d_ptr->resetToTheme(*activeTheme, i, true); + markSeriesVisualsDirty(); +} + +void Abstract3DController::setAxisX(QAbstract3DAxis *axis) +{ + // Setting null axis will always create new default axis + if (!axis || axis != m_axisX) { + setAxisHelper(QAbstract3DAxis::AxisOrientationX, axis, &m_axisX); + emit axisXChanged(m_axisX); + } } -Q3DAbstractAxis *Abstract3DController::axisX() +QAbstract3DAxis *Abstract3DController::axisX() { return m_axisX; } -void Abstract3DController::setAxisY(Q3DAbstractAxis *axis) +void Abstract3DController::setAxisY(QAbstract3DAxis *axis) { - setAxisHelper(Q3DAbstractAxis::AxisOrientationY, axis, &m_axisY); + // Setting null axis will always create new default axis + if (!axis || axis != m_axisY) { + setAxisHelper(QAbstract3DAxis::AxisOrientationY, axis, &m_axisY); + emit axisYChanged(m_axisY); + } } -Q3DAbstractAxis *Abstract3DController::axisY() +QAbstract3DAxis *Abstract3DController::axisY() { return m_axisY; } -void Abstract3DController::setAxisZ(Q3DAbstractAxis *axis) +void Abstract3DController::setAxisZ(QAbstract3DAxis *axis) { - setAxisHelper(Q3DAbstractAxis::AxisOrientationZ, axis, &m_axisZ); + // Setting null axis will always create new default axis + if (!axis || axis != m_axisZ) { + setAxisHelper(QAbstract3DAxis::AxisOrientationZ, axis, &m_axisZ); + emit axisZChanged(m_axisZ); + } } -Q3DAbstractAxis *Abstract3DController::axisZ() +QAbstract3DAxis *Abstract3DController::axisZ() { return m_axisZ; } -void Abstract3DController::addAxis(Q3DAbstractAxis *axis) +void Abstract3DController::addAxis(QAbstract3DAxis *axis) { Q_ASSERT(axis); Abstract3DController *owner = qobject_cast<Abstract3DController *>(axis->parent()); @@ -488,7 +543,7 @@ void Abstract3DController::addAxis(Q3DAbstractAxis *axis) m_axes.append(axis); } -void Abstract3DController::releaseAxis(Q3DAbstractAxis *axis) +void Abstract3DController::releaseAxis(QAbstract3DAxis *axis) { if (axis && m_axes.contains(axis)) { // Clear the default status from released default axes @@ -497,13 +552,13 @@ void Abstract3DController::releaseAxis(Q3DAbstractAxis *axis) // If the axis is in use, replace it with a temporary one switch (axis->orientation()) { - case Q3DAbstractAxis::AxisOrientationX: + case QAbstract3DAxis::AxisOrientationX: setAxisX(0); break; - case Q3DAbstractAxis::AxisOrientationY: + case QAbstract3DAxis::AxisOrientationY: setAxisY(0); break; - case Q3DAbstractAxis::AxisOrientationZ: + case QAbstract3DAxis::AxisOrientationZ: setAxisZ(0); break; default: @@ -515,7 +570,7 @@ void Abstract3DController::releaseAxis(Q3DAbstractAxis *axis) } } -QList<Q3DAbstractAxis *> Abstract3DController::axes() const +QList<QAbstract3DAxis *> Abstract3DController::axes() const { return m_axes; } @@ -525,7 +580,8 @@ void Abstract3DController::addInputHandler(QAbstract3DInputHandler *inputHandler Q_ASSERT(inputHandler); Abstract3DController *owner = qobject_cast<Abstract3DController *>(inputHandler->parent()); if (owner != this) { - Q_ASSERT_X(!owner, "addInputHandler", "Input handler already attached to another component."); + Q_ASSERT_X(!owner, "addInputHandler", + "Input handler already attached to another component."); inputHandler->setParent(this); } @@ -582,6 +638,11 @@ QAbstract3DInputHandler* Abstract3DController::activeInputHandler() return m_activeInputHandler; } +QList<QAbstract3DInputHandler *> Abstract3DController::inputHandlers() const +{ + return m_inputHandlers; +} + int Abstract3DController::zoomLevel() { return m_scene->activeCamera()->zoomLevel(); @@ -595,25 +656,46 @@ void Abstract3DController::setZoomLevel(int zoomLevel) emitNeedRender(); } -void Abstract3DController::setTheme(Q3DTheme *theme) +void Abstract3DController::addTheme(Q3DTheme *theme) +{ + m_themeManager->addTheme(theme); +} + +void Abstract3DController::releaseTheme(Q3DTheme *theme) +{ + Q3DTheme *oldTheme = m_themeManager->activeTheme(); + + m_themeManager->releaseTheme(theme); + + if (oldTheme != m_themeManager->activeTheme()) + emit activeThemeChanged(m_themeManager->activeTheme()); +} +QList<Q3DTheme *> Abstract3DController::themes() const +{ + return m_themeManager->themes(); +} + +void Abstract3DController::setActiveTheme(Q3DTheme *theme) { - if (theme != m_themeManager->theme()) { - m_themeManager->setTheme(theme); + if (theme != m_themeManager->activeTheme()) { + m_themeManager->setActiveTheme(theme); m_changeTracker.themeChanged = true; + // Default theme can be created by theme manager, so ensure we have correct theme + Q3DTheme *newActiveTheme = m_themeManager->activeTheme(); // Reset all attached series to the new theme for (int i = 0; i < m_seriesList.size(); i++) - m_seriesList.at(i)->d_ptr->resetToTheme(*theme, i, true); + m_seriesList.at(i)->d_ptr->resetToTheme(*newActiveTheme, i, true); markSeriesVisualsDirty(); - emit themeChanged(theme); + emit activeThemeChanged(newActiveTheme); } } -Q3DTheme *Abstract3DController::theme() const +Q3DTheme *Abstract3DController::activeTheme() const { - return m_themeManager->theme(); + return m_themeManager->activeTheme(); } -void Abstract3DController::setSelectionMode(QDataVis::SelectionFlags mode) +void Abstract3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { if (mode != m_selectionMode) { m_selectionMode = mode; @@ -623,12 +705,12 @@ void Abstract3DController::setSelectionMode(QDataVis::SelectionFlags mode) } } -QDataVis::SelectionFlags Abstract3DController::selectionMode() const +QAbstract3DGraph::SelectionFlags Abstract3DController::selectionMode() const { return m_selectionMode; } -void Abstract3DController::setShadowQuality(QDataVis::ShadowQuality quality) +void Abstract3DController::setShadowQuality(QAbstract3DGraph::ShadowQuality quality) { if (quality != m_shadowQuality) { m_shadowQuality = quality; @@ -638,7 +720,7 @@ void Abstract3DController::setShadowQuality(QDataVis::ShadowQuality quality) } } -QDataVis::ShadowQuality Abstract3DController::shadowQuality() const +QAbstract3DGraph::ShadowQuality Abstract3DController::shadowQuality() const { return m_shadowQuality; } @@ -776,7 +858,7 @@ void Abstract3DController::handleAxisAutoAdjustRangeChanged(bool autoAdjust) if (sender != m_axisX && sender != m_axisY && sender != m_axisZ) return; - Q3DAbstractAxis *axis = static_cast<Q3DAbstractAxis*>(sender); + QAbstract3DAxis *axis = static_cast<QAbstract3DAxis*>(sender); handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), autoAdjust); } @@ -786,15 +868,15 @@ void Abstract3DController::handleAxisLabelFormatChanged(const QString &format) handleAxisLabelFormatChangedBySender(sender()); } -void Abstract3DController::handleInputStateChanged(QAbstract3DInputHandler::InputState state) +void Abstract3DController::handleInputViewChanged(QAbstract3DInputHandler::InputView view) { - // When in automatic slicing mode, input state change to overview disables slice mode - if (m_selectionMode.testFlag(QDataVis::SelectionSlice) - && state == QAbstract3DInputHandler::InputStateOnPrimaryView) { + // When in automatic slicing mode, input view change to primary disables slice mode + if (m_selectionMode.testFlag(QAbstract3DGraph::SelectionSlice) + && view == QAbstract3DInputHandler::InputViewOnPrimary) { setSlicingActive(false); } - m_changeTracker.inputStateChanged = true; + m_changeTracker.inputViewChanged = true; emitNeedRender(); } @@ -813,7 +895,7 @@ void Abstract3DController::handleSeriesVisibilityChanged(bool visible) handleSeriesVisibilityChangedBySender(sender()); } -void Abstract3DController::handleRequestShadowQuality(QDataVis::ShadowQuality quality) +void Abstract3DController::handleRequestShadowQuality(QAbstract3DGraph::ShadowQuality quality) { setShadowQuality(quality); } @@ -845,15 +927,15 @@ void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender emitNeedRender(); } -void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, - Q3DAbstractAxis *axis, Q3DAbstractAxis **axisPtr) +void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orientation, + QAbstract3DAxis *axis, QAbstract3DAxis **axisPtr) { // Setting null axis indicates using default axis if (!axis) axis = createDefaultAxis(orientation); // If old axis is default axis, delete it - Q3DAbstractAxis *oldAxis = *axisPtr; + QAbstract3DAxis *oldAxis = *axisPtr; if (oldAxis) { if (oldAxis->d_ptr->isDefaultAxis()) { m_axes.removeAll(oldAxis); @@ -862,7 +944,7 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient } else { // Disconnect the old axis from use QObject::disconnect(oldAxis, 0, this, 0); - oldAxis->d_ptr->setOrientation(Q3DAbstractAxis::AxisOrientationNone); + oldAxis->d_ptr->setOrientation(QAbstract3DAxis::AxisOrientationNone); } } @@ -874,20 +956,20 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient axis->d_ptr->setOrientation(orientation); - QObject::connect(axis, &Q3DAbstractAxis::titleChanged, + QObject::connect(axis, &QAbstract3DAxis::titleChanged, this, &Abstract3DController::handleAxisTitleChanged); - QObject::connect(axis, &Q3DAbstractAxis::labelsChanged, + QObject::connect(axis, &QAbstract3DAxis::labelsChanged, this, &Abstract3DController::handleAxisLabelsChanged); - QObject::connect(axis, &Q3DAbstractAxis::rangeChanged, + QObject::connect(axis, &QAbstract3DAxis::rangeChanged, this, &Abstract3DController::handleAxisRangeChanged); - QObject::connect(axis, &Q3DAbstractAxis::autoAdjustRangeChanged, + QObject::connect(axis, &QAbstract3DAxis::autoAdjustRangeChanged, this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); - if (orientation == Q3DAbstractAxis::AxisOrientationX) + if (orientation == QAbstract3DAxis::AxisOrientationX) m_changeTracker.axisXTypeChanged = true; - else if (orientation == Q3DAbstractAxis::AxisOrientationY) + else if (orientation == QAbstract3DAxis::AxisOrientationY) m_changeTracker.axisYTypeChanged = true; - else if (orientation == Q3DAbstractAxis::AxisOrientationZ) + else if (orientation == QAbstract3DAxis::AxisOrientationZ) m_changeTracker.axisZTypeChanged = true; handleAxisTitleChangedBySender(axis); @@ -896,13 +978,13 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), axis->isAutoAdjustRange()); - if (axis->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(axis); - QObject::connect(valueAxis, &Q3DValueAxis::segmentCountChanged, + if (axis->type() & QAbstract3DAxis::AxisTypeValue) { + QValue3DAxis *valueAxis = static_cast<QValue3DAxis *>(axis); + QObject::connect(valueAxis, &QValue3DAxis::segmentCountChanged, this, &Abstract3DController::handleAxisSegmentCountChanged); - QObject::connect(valueAxis, &Q3DValueAxis::subSegmentCountChanged, + QObject::connect(valueAxis, &QValue3DAxis::subSegmentCountChanged, this, &Abstract3DController::handleAxisSubSegmentCountChanged); - QObject::connect(valueAxis, &Q3DValueAxis::labelFormatChanged, + QObject::connect(valueAxis, &QValue3DAxis::labelFormatChanged, this, &Abstract3DController::handleAxisLabelFormatChanged); handleAxisSegmentCountChangedBySender(valueAxis); @@ -911,33 +993,38 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient } } -Q3DAbstractAxis *Abstract3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation) +QAbstract3DAxis *Abstract3DController::createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation) { Q_UNUSED(orientation) // The default default axis is a value axis. If the graph type has a different default axis // for some orientation, this function needs to be overridden. - Q3DAbstractAxis *defaultAxis = createDefaultValueAxis(); + QAbstract3DAxis *defaultAxis = createDefaultValueAxis(); return defaultAxis; } -Q3DValueAxis *Abstract3DController::createDefaultValueAxis() +QValue3DAxis *Abstract3DController::createDefaultValueAxis() { // Default value axis has single segment, empty label format, and auto scaling - Q3DValueAxis *defaultAxis = new Q3DValueAxis; + QValue3DAxis *defaultAxis = new QValue3DAxis; defaultAxis->d_ptr->setDefaultAxis(true); return defaultAxis; } -Q3DCategoryAxis *Abstract3DController::createDefaultCategoryAxis() +QCategory3DAxis *Abstract3DController::createDefaultCategoryAxis() { // Default category axis has no labels - Q3DCategoryAxis *defaultAxis = new Q3DCategoryAxis; + QCategory3DAxis *defaultAxis = new QCategory3DAxis; defaultAxis->d_ptr->setDefaultAxis(true); return defaultAxis; } +void Abstract3DController::startRecordingRemovesAndInserts() +{ + // Default implementation does nothing +} + void Abstract3DController::emitNeedRender() { if (!m_renderPending) { @@ -946,4 +1033,4 @@ void Abstract3DController::emitNeedRender() } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index c56b8a72..cac46ddf 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -30,7 +30,7 @@ #define ABSTRACT3DCONTROLLER_P_H #include "datavisualizationglobal_p.h" -#include "q3dabstractaxis.h" +#include "qabstract3daxis.h" #include "drawer_p.h" #include "qabstract3dinputhandler.h" #include "qabstractdataproxy.h" @@ -42,7 +42,7 @@ class QFont; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class CameraHelper; class Abstract3DRenderer; @@ -76,7 +76,7 @@ struct Abstract3DChangeBitField { bool axisXLabelFormatChanged : 1; bool axisYLabelFormatChanged : 1; bool axisZLabelFormatChanged : 1; - bool inputStateChanged : 1; + bool inputViewChanged : 1; bool inputPositionChanged : 1; Abstract3DChangeBitField() : @@ -136,20 +136,20 @@ private: GLfloat m_horizontalRotation; GLfloat m_verticalRotation; ThemeManager *m_themeManager; - QDataVis::SelectionFlags m_selectionMode; - QDataVis::ShadowQuality m_shadowQuality; - Q3DScene *m_scene; + QAbstract3DGraph::SelectionFlags m_selectionMode; + QAbstract3DGraph::ShadowQuality m_shadowQuality; protected: + Q3DScene *m_scene; QList<QAbstract3DInputHandler *> m_inputHandlers; // List of all added input handlers QAbstract3DInputHandler *m_activeInputHandler; CameraHelper *m_cameraHelper; // Active axes - Q3DAbstractAxis *m_axisX; - Q3DAbstractAxis *m_axisY; - Q3DAbstractAxis *m_axisZ; + QAbstract3DAxis *m_axisX; + QAbstract3DAxis *m_axisY; + QAbstract3DAxis *m_axisZ; - QList<Q3DAbstractAxis *> m_axes; // List of all added axes + QList<QAbstract3DAxis *> m_axes; // List of all added axes Abstract3DRenderer *m_renderer; bool m_isDataDirty; bool m_isSeriesVisibilityDirty; @@ -158,10 +158,10 @@ protected: QList<QAbstract3DSeries *> m_seriesList; - explicit Abstract3DController(QRect initialViewport, QObject *parent = 0); - virtual ~Abstract3DController(); + explicit Abstract3DController(QRect initialViewport, Q3DScene *scene, QObject *parent = 0); public: + virtual ~Abstract3DController(); inline bool isInitialized() { return (m_renderer != 0); } virtual void synchDataToRenderer(); @@ -170,35 +170,40 @@ public: void setRenderer(Abstract3DRenderer *renderer); virtual void addSeries(QAbstract3DSeries *series); + virtual void insertSeries(int index, QAbstract3DSeries *series); virtual void removeSeries(QAbstract3DSeries *series); QList<QAbstract3DSeries *> seriesList(); - virtual void setAxisX(Q3DAbstractAxis *axis); - virtual Q3DAbstractAxis *axisX(); - virtual void setAxisY(Q3DAbstractAxis *axis); - virtual Q3DAbstractAxis *axisY(); - virtual void setAxisZ(Q3DAbstractAxis *axis); - virtual Q3DAbstractAxis *axisZ(); - virtual void addAxis(Q3DAbstractAxis *axis); - virtual void releaseAxis(Q3DAbstractAxis *axis); - virtual QList<Q3DAbstractAxis *> axes() const; // Omits default axes + virtual void setAxisX(QAbstract3DAxis *axis); + virtual QAbstract3DAxis *axisX(); + virtual void setAxisY(QAbstract3DAxis *axis); + virtual QAbstract3DAxis *axisY(); + virtual void setAxisZ(QAbstract3DAxis *axis); + virtual QAbstract3DAxis *axisZ(); + virtual void addAxis(QAbstract3DAxis *axis); + virtual void releaseAxis(QAbstract3DAxis *axis); + virtual QList<QAbstract3DAxis *> axes() const; // Omits default axes virtual void addInputHandler(QAbstract3DInputHandler *inputHandler); virtual void releaseInputHandler(QAbstract3DInputHandler *inputHandler); virtual void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); virtual QAbstract3DInputHandler *activeInputHandler(); + virtual QList<QAbstract3DInputHandler *> inputHandlers() const; virtual int zoomLevel(); virtual void setZoomLevel(int zoomLevel); - virtual void setTheme(Q3DTheme *theme); - virtual Q3DTheme *theme() const; + virtual void addTheme(Q3DTheme *theme); + virtual void releaseTheme(Q3DTheme *theme); + virtual void setActiveTheme(Q3DTheme *theme); + virtual Q3DTheme *activeTheme() const; + virtual QList<Q3DTheme *> themes() const; - virtual void setSelectionMode(QDataVis::SelectionFlags mode); - virtual QDataVis::SelectionFlags selectionMode() const; + virtual void setSelectionMode(QAbstract3DGraph::SelectionFlags mode); + virtual QAbstract3DGraph::SelectionFlags selectionMode() const; - virtual void setShadowQuality(QDataVis::ShadowQuality quality); - virtual QDataVis::ShadowQuality shadowQuality() const; + virtual void setShadowQuality(QAbstract3DGraph::ShadowQuality quality); + virtual QAbstract3DGraph::ShadowQuality shadowQuality() const; bool isSlicingActive() const; void setSlicingActive(bool isSlicing); @@ -210,6 +215,8 @@ public: void emitNeedRender(); + virtual void clearSelection() = 0; + virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void touchEvent(QTouchEvent *event); virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos); @@ -223,9 +230,10 @@ public: virtual void handleAxisSegmentCountChangedBySender(QObject *sender); virtual void handleAxisSubSegmentCountChangedBySender(QObject *sender); virtual void handleAxisAutoAdjustRangeChangedInOrientation( - Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) = 0; + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) = 0; virtual void handleAxisLabelFormatChangedBySender(QObject *sender); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); + virtual void handlePendingClick() = 0; public slots: void handleAxisTitleChanged(const QString &title); @@ -235,7 +243,7 @@ public slots: void handleAxisSubSegmentCountChanged(int count); void handleAxisAutoAdjustRangeChanged(bool autoAdjust); void handleAxisLabelFormatChanged(const QString &format); - void handleInputStateChanged(QAbstract3DInputHandler::InputState state); + void handleInputViewChanged(QAbstract3DInputHandler::InputView view); void handleInputPositionChanged(const QPoint &position); void handleSeriesVisibilityChanged(bool visible); @@ -246,29 +254,34 @@ public slots: void handleThemeSingleHighlightGradientChanged(const QLinearGradient &gradient); void handleThemeMultiHighlightColorChanged(const QColor &color); void handleThemeMultiHighlightGradientChanged(const QLinearGradient &gradient); + void handleThemeTypeChanged(Q3DTheme::Theme theme); // Renderer callback handlers - void handleRequestShadowQuality(QDataVis::ShadowQuality quality); + void handleRequestShadowQuality(QAbstract3DGraph::ShadowQuality quality); signals: - void shadowQualityChanged(QDataVis::ShadowQuality quality); + void shadowQualityChanged(QAbstract3DGraph::ShadowQuality quality); void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); - void themeChanged(Q3DTheme *theme); - void selectionModeChanged(QDataVis::SelectionFlags mode); + void activeThemeChanged(Q3DTheme *activeTheme); + void selectionModeChanged(QAbstract3DGraph::SelectionFlags mode); void needRender(); + void axisXChanged(QAbstract3DAxis *axis); + void axisYChanged(QAbstract3DAxis *axis); + void axisZChanged(QAbstract3DAxis *axis); protected: - virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation); - Q3DValueAxis *createDefaultValueAxis(); - Q3DCategoryAxis *createDefaultCategoryAxis(); + virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation); + QValue3DAxis *createDefaultValueAxis(); + QCategory3DAxis *createDefaultCategoryAxis(); + virtual void startRecordingRemovesAndInserts(); private: - void setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis *axis, - Q3DAbstractAxis **axisPtr); + void setAxisHelper(QAbstract3DAxis::AxisOrientation orientation, QAbstract3DAxis *axis, + QAbstract3DAxis **axisPtr); friend class Bars3DController; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 74088b7c..7824000e 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -17,7 +17,7 @@ ****************************************************************************/ #include "abstract3drenderer_p.h" -#include "q3dvalueaxis.h" +#include "qvalue3daxis.h" #include "texturehelper_p.h" #include "utils_p.h" #include "q3dscene_p.h" @@ -27,27 +27,28 @@ #include "q3dtheme_p.h" #include "objecthelper_p.h" -Q_DECLARE_METATYPE(QtDataVisualization::QDataVis::ShadowQuality) - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) : QObject(0), m_hasNegativeValues(false), m_cachedTheme(new Q3DTheme()), m_drawer(new Drawer(m_cachedTheme)), - m_cachedShadowQuality(QDataVis::ShadowQualityMedium), + m_cachedShadowQuality(QAbstract3DGraph::ShadowQualityMedium), m_autoScaleAdjustment(1.0f), - m_cachedSelectionMode(QDataVis::SelectionNone), + m_cachedSelectionMode(QAbstract3DGraph::SelectionNone), m_textureHelper(0), m_cachedScene(new Q3DScene()), m_selectionDirty(true), m_selectionState(SelectNone), - m_devicePixelRatio(1.0f) - #ifdef DISPLAY_RENDER_SPEED + m_devicePixelRatio(1.0f), + m_selectionLabelDirty(true), + m_clickPending(false), + m_clickedSeries(0) +#ifdef DISPLAY_RENDER_SPEED , m_isFirstFrame(true), m_numFrames(0) - #endif +#endif { QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); @@ -85,9 +86,9 @@ void Abstract3DRenderer::initializeOpenGL() m_textureHelper = new TextureHelper(); m_drawer->initializeOpenGL(); - axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationX).setDrawer(m_drawer); - axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationY).setDrawer(m_drawer); - axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationZ).setDrawer(m_drawer); + axisCacheForOrientation(QAbstract3DAxis::AxisOrientationX).setDrawer(m_drawer); + axisCacheForOrientation(QAbstract3DAxis::AxisOrientationY).setDrawer(m_drawer); + axisCacheForOrientation(QAbstract3DAxis::AxisOrientationZ).setDrawer(m_drawer); } void Abstract3DRenderer::render(const GLuint defaultFboHandle) @@ -102,7 +103,8 @@ void Abstract3DRenderer::render(const GLuint defaultFboHandle) // Measure speed (as milliseconds per frame) m_numFrames++; if (m_lastFrameTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago - qDebug() << float(m_lastFrameTime.elapsed()) / float(m_numFrames) << "ms/frame (=" << float(m_numFrames) << "fps)"; + qDebug() << float(m_lastFrameTime.elapsed()) / float(m_numFrames) << "ms/frame (=" + << float(m_numFrames) << "fps)"; m_numFrames = 0; m_lastFrameTime.restart(); } @@ -122,9 +124,15 @@ void Abstract3DRenderer::render(const GLuint defaultFboHandle) m_viewport.y(), m_viewport.width(), m_viewport.height()); + glScissor(m_viewport.x(), + m_viewport.y(), + m_viewport.width(), + m_viewport.height()); + glEnable(GL_SCISSOR_TEST); QVector3D clearColor = Utils::vectorFromColor(m_cachedTheme->windowColor()); glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); } QString Abstract3DRenderer::generateValueLabel(const QString &format, float value) @@ -145,7 +153,8 @@ void Abstract3DRenderer::updateInputPosition(const QPoint &position) m_inputPosition = position; } -void Abstract3DRenderer::initGradientShaders(const QString &vertexShader, const QString &fragmentShader) +void Abstract3DRenderer::initGradientShaders(const QString &vertexShader, + const QString &fragmentShader) { // Do nothing by default Q_UNUSED(vertexShader) @@ -155,14 +164,10 @@ void Abstract3DRenderer::initGradientShaders(const QString &vertexShader, const void Abstract3DRenderer::updateTheme(Q3DTheme *theme) { // Synchronize the controller theme with renderer - bool changed = theme->d_ptr->sync(*m_cachedTheme->d_ptr); + bool updateDrawer = theme->d_ptr->sync(*m_cachedTheme->d_ptr); - if (changed) { - // Update drawer if sync changed something + if (updateDrawer) m_drawer->setTheme(m_cachedTheme); - // Re-initialize shaders - reInitShaders(); - } } void Abstract3DRenderer::updateScene(Q3DScene *scene) @@ -189,11 +194,15 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) updateInputPosition(QPoint(logicalPixelPosition.x() * m_devicePixelRatio, logicalPixelPosition.y() * m_devicePixelRatio)); + // Synchronize the renderer scene to controller scene + scene->d_ptr->sync(*m_cachedScene->d_ptr); + if (Q3DScene::invalidSelectionPoint() == logicalPixelPosition) { updateSelectionState(SelectNone); } else { // Selections are one-shot, reset selection active to false before processing scene->setSelectionQueryPosition(Q3DScene::invalidSelectionPoint()); + m_clickPending = true; if (scene->isSlicingActive()) { if (scene->isPointInPrimarySubView(logicalPixelPosition)) @@ -206,15 +215,12 @@ void Abstract3DRenderer::updateScene(Q3DScene *scene) updateSelectionState(SelectOnScene); } } - - // Synchronize the controller scene with renderer - scene->d_ptr->sync(*m_cachedScene->d_ptr); } void Abstract3DRenderer::reInitShaders() { #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { initGradientShaders(QStringLiteral(":/shaders/vertexShadow"), QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY")); initShaders(QStringLiteral(":/shaders/vertexShadow"), @@ -244,15 +250,15 @@ void Abstract3DRenderer::handleShadowQualityChange() reInitShaders(); #if defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality != QDataVis::ShadowQualityNone) { - emit requestShadowQuality(QDataVis::ShadowQualityNone); + if (m_cachedShadowQuality != QAbstract3DGraph::ShadowQualityNone) { + emit requestShadowQuality(QAbstract3DGraph::ShadowQualityNone); qWarning("Shadows are not yet supported for OpenGL ES2"); - m_cachedShadowQuality = QDataVis::ShadowQualityNone; + m_cachedShadowQuality = QAbstract3DGraph::ShadowQualityNone; } #endif } -void Abstract3DRenderer::updateSelectionMode(QDataVis::SelectionFlags mode) +void Abstract3DRenderer::updateSelectionMode(QAbstract3DGraph::SelectionFlags mode) { m_cachedSelectionMode = mode; m_selectionDirty = true; @@ -280,39 +286,46 @@ void Abstract3DRenderer::handleResize() #endif } -void Abstract3DRenderer::updateAxisType(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis::AxisType type) +void Abstract3DRenderer::updateAxisType(QAbstract3DAxis::AxisOrientation orientation, + QAbstract3DAxis::AxisType type) { axisCacheForOrientation(orientation).setType(type); } -void Abstract3DRenderer::updateAxisTitle(Q3DAbstractAxis::AxisOrientation orientation, const QString &title) +void Abstract3DRenderer::updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation, + const QString &title) { axisCacheForOrientation(orientation).setTitle(title); } -void Abstract3DRenderer::updateAxisLabels(Q3DAbstractAxis::AxisOrientation orientation, const QStringList &labels) +void Abstract3DRenderer::updateAxisLabels(QAbstract3DAxis::AxisOrientation orientation, + const QStringList &labels) { axisCacheForOrientation(orientation).setLabels(labels); } -void Abstract3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, float min, float max) +void Abstract3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, + float min, float max) { AxisRenderCache &cache = axisCacheForOrientation(orientation); cache.setMin(min); cache.setMax(max); } -void Abstract3DRenderer::updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count) +void Abstract3DRenderer::updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation, + int count) { axisCacheForOrientation(orientation).setSegmentCount(count); } -void Abstract3DRenderer::updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count) +void Abstract3DRenderer::updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientation orientation, + int count) { axisCacheForOrientation(orientation).setSubSegmentCount(count); } -void Abstract3DRenderer::updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientation orientation, const QString &format) +void Abstract3DRenderer::updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, + const QString &format) { axisCacheForOrientation(orientation).setLabelFormat(format); } @@ -348,19 +361,26 @@ void Abstract3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLi visibleCount = 0; } foreach (QAbstract3DSeries *current, seriesList) { - if (current->isVisible()) + if (current->isVisible()) { + // Item selection label may need update + if (current->d_ptr->m_changeTracker.nameChanged + || current->d_ptr->m_changeTracker.itemLabelFormatChanged) { + m_selectionLabelDirty = true; + } m_visibleSeriesList[visibleCount++].populate(current, this); + } } } -AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation) +AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation( + QAbstract3DAxis::AxisOrientation orientation) { switch (orientation) { - case Q3DAbstractAxis::AxisOrientationX: + case QAbstract3DAxis::AxisOrientationX: return m_axisCacheX; - case Q3DAbstractAxis::AxisOrientationY: + case QAbstract3DAxis::AxisOrientationY: return m_axisCacheY; - case Q3DAbstractAxis::AxisOrientationZ: + case QAbstract3DAxis::AxisOrientationZ: return m_axisCacheZ; default: qFatal("Abstract3DRenderer::axisCacheForOrientation"); @@ -370,32 +390,32 @@ AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(Q3DAbstractAxis::Ax void Abstract3DRenderer::lowerShadowQuality() { - QDataVis::ShadowQuality newQuality = QDataVis::ShadowQualityNone; + QAbstract3DGraph::ShadowQuality newQuality = QAbstract3DGraph::ShadowQualityNone; switch (m_cachedShadowQuality) { - case QDataVis::ShadowQualityHigh: + case QAbstract3DGraph::ShadowQualityHigh: qWarning("Creating high quality shadows failed. Changing to medium quality."); - newQuality = QDataVis::ShadowQualityMedium; + newQuality = QAbstract3DGraph::ShadowQualityMedium; break; - case QDataVis::ShadowQualityMedium: + case QAbstract3DGraph::ShadowQualityMedium: qWarning("Creating medium quality shadows failed. Changing to low quality."); - newQuality = QDataVis::ShadowQualityLow; + newQuality = QAbstract3DGraph::ShadowQualityLow; break; - case QDataVis::ShadowQualityLow: + case QAbstract3DGraph::ShadowQualityLow: qWarning("Creating low quality shadows failed. Switching shadows off."); - newQuality = QDataVis::ShadowQualityNone; + newQuality = QAbstract3DGraph::ShadowQualityNone; break; - case QDataVis::ShadowQualitySoftHigh: + case QAbstract3DGraph::ShadowQualitySoftHigh: qWarning("Creating soft high quality shadows failed. Changing to soft medium quality."); - newQuality = QDataVis::ShadowQualitySoftMedium; + newQuality = QAbstract3DGraph::ShadowQualitySoftMedium; break; - case QDataVis::ShadowQualitySoftMedium: + case QAbstract3DGraph::ShadowQualitySoftMedium: qWarning("Creating soft medium quality shadows failed. Changing to soft low quality."); - newQuality = QDataVis::ShadowQualitySoftLow; + newQuality = QAbstract3DGraph::ShadowQualitySoftLow; break; - case QDataVis::ShadowQualitySoftLow: + case QAbstract3DGraph::ShadowQualitySoftLow: qWarning("Creating soft low quality shadows failed. Switching shadows off."); - newQuality = QDataVis::ShadowQualityNone; + newQuality = QAbstract3DGraph::ShadowQualityNone; break; default: // You'll never get here @@ -406,7 +426,8 @@ void Abstract3DRenderer::lowerShadowQuality() updateShadowQuality(newQuality); } -void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture) +void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient, + GLuint *gradientTexture) { // Readjust start/stop to match gradient texture size gradient->setStart(qreal(gradientTextureWidth), qreal(gradientTextureHeight)); @@ -420,4 +441,4 @@ void Abstract3DRenderer::fixGradientAndGenerateTexture(QLinearGradient *gradient *gradientTexture = m_textureHelper->createGradientTexture(*gradient); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 17a55ac9..e7591a10 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -29,9 +29,12 @@ #ifndef ABSTRACT3DRENDERER_P_H #define ABSTRACT3DRENDERER_P_H +//#define DISPLAY_RENDER_SPEED + #include <QtGui/QOpenGLFunctions> -#include <QtGui/QFont> +#ifdef DISPLAY_RENDER_SPEED #include <QTime> +#endif #include "datavisualizationglobal_p.h" #include "abstract3dcontroller_p.h" @@ -39,9 +42,7 @@ #include "qabstractdataproxy.h" #include "seriesrendercache_p.h" -//#define DISPLAY_RENDER_SPEED - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class TextureHelper; class Theme; @@ -70,7 +71,7 @@ public: virtual void render(GLuint defaultFboHandle); virtual void updateTheme(Q3DTheme *theme); - virtual void updateSelectionMode(QDataVis::SelectionFlags newMode); + virtual void updateSelectionMode(QAbstract3DGraph::SelectionFlags newMode); virtual void updateScene(Q3DScene *scene); virtual void updateTextures() = 0; virtual void initSelectionBuffer() = 0; @@ -80,24 +81,28 @@ public: #if !defined(QT_OPENGL_ES_2) virtual void updateDepthBuffer() = 0; #endif - virtual void updateShadowQuality(QDataVis::ShadowQuality quality) = 0; + virtual void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality) = 0; virtual void initShaders(const QString &vertexShader, const QString &fragmentShader) = 0; virtual void initGradientShaders(const QString &vertexShader, const QString &fragmentShader); virtual void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader) = 0; - virtual void updateAxisType(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis::AxisType type); - virtual void updateAxisTitle(Q3DAbstractAxis::AxisOrientation orientation, const QString &title); - virtual void updateAxisLabels(Q3DAbstractAxis::AxisOrientation orientation, const QStringList &labels); - virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, float min, float max); - virtual void updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count); - virtual void updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count); - virtual void updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientation orientation, const QString &format); + virtual void updateAxisType(QAbstract3DAxis::AxisOrientation orientation, QAbstract3DAxis::AxisType type); + virtual void updateAxisTitle(QAbstract3DAxis::AxisOrientation orientation, const QString &title); + virtual void updateAxisLabels(QAbstract3DAxis::AxisOrientation orientation, const QStringList &labels); + virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max); + virtual void updateAxisSegmentCount(QAbstract3DAxis::AxisOrientation orientation, int count); + virtual void updateAxisSubSegmentCount(QAbstract3DAxis::AxisOrientation orientation, int count); + virtual void updateAxisLabelFormat(QAbstract3DAxis::AxisOrientation orientation, const QString &format); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); void fixGradientAndGenerateTexture(QLinearGradient *gradient, GLuint *gradientTexture); + inline bool isClickPending() { return m_clickPending; } + inline void clearClickPending() { m_clickPending = false; } + inline QAbstract3DSeries *clickedSeries() const { return m_clickedSeries; } + signals: void needRender(); // Emit this if something in renderer causes need for another render pass. - void requestShadowQuality(QDataVis::ShadowQuality quality); // For automatic quality adjustments + void requestShadowQuality(QAbstract3DGraph::ShadowQuality quality); // For automatic quality adjustments protected: Abstract3DRenderer(Abstract3DController *controller); @@ -108,7 +113,7 @@ protected: virtual void handleShadowQualityChange(); virtual void handleResize(); - AxisRenderCache &axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation); + AxisRenderCache &axisCacheForOrientation(QAbstract3DAxis::AxisOrientation orientation); virtual void lowerShadowQuality(); @@ -118,10 +123,10 @@ protected: Q3DTheme *m_cachedTheme; Drawer *m_drawer; QRect m_viewport; - QDataVis::ShadowQuality m_cachedShadowQuality; + QAbstract3DGraph::ShadowQuality m_cachedShadowQuality; GLfloat m_autoScaleAdjustment; - QDataVis::SelectionFlags m_cachedSelectionMode; + QAbstract3DGraph::SelectionFlags m_cachedSelectionMode; AxisRenderCache m_axisCacheX; AxisRenderCache m_axisCacheY; @@ -137,6 +142,9 @@ protected: QRect m_primarySubViewport; QRect m_secondarySubViewport; float m_devicePixelRatio; + bool m_selectionLabelDirty; + bool m_clickPending; + QAbstract3DSeries *m_clickedSeries; #ifdef DISPLAY_RENDER_SPEED bool m_isFirstFrame; @@ -145,6 +153,6 @@ protected: #endif }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // ABSTRACT3DRENDERER_P_H +#endif diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp index f7960b2b..c1c2d5bd 100644 --- a/src/datavisualization/engine/axisrendercache.cpp +++ b/src/datavisualization/engine/axisrendercache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -20,10 +20,10 @@ #include "qmath.h" #include <QFontMetrics> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION AxisRenderCache::AxisRenderCache() - : m_type(Q3DAbstractAxis::AxisTypeNone), + : m_type(QAbstract3DAxis::AxisTypeNone), m_min(0.0f), m_max(10.0f), m_segmentCount(5), @@ -51,7 +51,7 @@ void AxisRenderCache::setDrawer(Drawer *drawer) } } -void AxisRenderCache::setType(Q3DAbstractAxis::AxisType type) +void AxisRenderCache::setType(QAbstract3DAxis::AxisType type) { m_type = type; @@ -183,4 +183,4 @@ int AxisRenderCache::maxLabelWidth(const QStringList &labels) const return labelWidth; } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h index cddc7839..e1c51e7c 100644 --- a/src/datavisualization/engine/axisrendercache_p.h +++ b/src/datavisualization/engine/axisrendercache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -31,10 +31,10 @@ #include "datavisualizationglobal_p.h" #include "labelitem_p.h" -#include "q3dabstractaxis_p.h" +#include "qabstract3daxis_p.h" #include "drawer_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class AxisRenderCache : public QObject { @@ -45,8 +45,8 @@ public: void setDrawer(Drawer *drawer); - void setType(Q3DAbstractAxis::AxisType type); - inline Q3DAbstractAxis::AxisType type() const { return m_type; } + void setType(QAbstract3DAxis::AxisType type); + inline QAbstract3DAxis::AxisType type() const { return m_type; } void setTitle(const QString &title); inline const QString &title() { return m_title; } void setLabels(const QStringList &labels); @@ -76,7 +76,7 @@ private: int maxLabelWidth(const QStringList &labels) const; // Cached axis values - Q3DAbstractAxis::AxisType m_type; + QAbstract3DAxis::AxisType m_type; QString m_title; QStringList m_labels; float m_min; @@ -96,6 +96,6 @@ private: Q_DISABLE_COPY(AxisRenderCache) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 5232a566..5bd37ccf 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,9 +19,9 @@ #include "bars3dcontroller_p.h" #include "bars3drenderer_p.h" #include "camerahelper_p.h" -#include "q3dabstractaxis_p.h" -#include "q3dvalueaxis_p.h" -#include "q3dcategoryaxis_p.h" +#include "qabstract3daxis_p.h" +#include "qvalue3daxis_p.h" +#include "qcategory3daxis_p.h" #include "qbardataproxy_p.h" #include "qbar3dseries_p.h" #include "thememanager_p.h" @@ -30,12 +30,14 @@ #include <QMatrix4x4> #include <qmath.h> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -Bars3DController::Bars3DController(QRect boundRect) - : Abstract3DController(boundRect), +Bars3DController::Bars3DController(QRect boundRect, Q3DScene *scene) + : Abstract3DController(boundRect, scene), m_selectedBar(invalidSelectionPosition()), m_selectedBarSeries(0), + m_primarySeries(0), + m_isMultiSeriesUniform(false), m_isBarSpecRelative(true), m_barThicknessRatio(1.0f), m_barSpacing(QSizeF(1.0, 1.0)), @@ -64,15 +66,16 @@ void Bars3DController::initializeOpenGL() setRenderer(m_renderer); synchDataToRenderer(); - QObject::connect(m_renderer, &Bars3DRenderer::barClicked, this, - &Bars3DController::handleBarClicked, Qt::QueuedConnection); emitNeedRender(); } void Bars3DController::synchDataToRenderer() { + if (!isInitialized()) + return; + // Background change requires reloading the meshes in bar graphs, so dirty the series visuals - if (m_themeManager->theme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { + if (m_themeManager->activeTheme()->d_ptr->m_dirtyBits.backgroundEnabledDirty) { m_isSeriesVisualsDirty = true; foreach (QAbstract3DSeries *series, m_seriesList) series->d_ptr->m_changeTracker.meshChanged = true; @@ -80,10 +83,12 @@ void Bars3DController::synchDataToRenderer() Abstract3DController::synchDataToRenderer(); - if (!isInitialized()) - return; - // Notify changes to renderer + if (m_changeTracker.multiSeriesScalingChanged) { + m_renderer->updateMultiSeriesScaling(m_isMultiSeriesUniform); + m_changeTracker.multiSeriesScalingChanged = false; + } + if (m_changeTracker.barSpecsChanged) { m_renderer->updateBarSpecs(m_barThicknessRatio, m_barSpacing, m_isBarSpecRelative); m_changeTracker.barSpecsChanged = false; @@ -98,8 +103,11 @@ void Bars3DController::synchDataToRenderer() void Bars3DController::handleArrayReset() { - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } // Clear selection unless still valid setSelectedBar(m_selectedBar, m_selectedBarSeries); emitNeedRender(); @@ -109,8 +117,11 @@ void Bars3DController::handleRowsAdded(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -118,8 +129,11 @@ void Bars3DController::handleRowsChanged(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -127,11 +141,25 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; - // Clear selection unless still valid - setSelectedBar(m_selectedBar, m_selectedBarSeries); + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series == m_selectedBarSeries) { + // If rows removed from selected series before the selection, adjust the selection + int selectedRow = m_selectedBar.x(); + if (startIndex <= selectedRow) { + if ((startIndex + count) > selectedRow) + selectedRow = -1; // Selected row removed + else + selectedRow -= count; // Move selected row down by amount of rows removed + + setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries); + } + } + + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -140,8 +168,21 @@ void Bars3DController::handleRowsInserted(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series == m_selectedBarSeries) { + // If rows inserted to selected series before the selection, adjust the selection + int selectedRow = m_selectedBar.x(); + if (startIndex <= selectedRow) { + selectedRow += count; + setSelectedBar(QPoint(selectedRow, m_selectedBar.y()), m_selectedBarSeries); + } + } + + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } + emitNeedRender(); } @@ -149,50 +190,44 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) { Q_UNUSED(rowIndex) Q_UNUSED(columnIndex) - adjustAxisRanges(); - m_isDataDirty = true; + QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustAxisRanges(); + m_isDataDirty = true; + } emitNeedRender(); } void Bars3DController::handleDataRowLabelsChanged() { - QBar3DSeries *firstSeries = 0; - if (m_seriesList.size()) - firstSeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); - if (m_axisZ && firstSeries && firstSeries->dataProxy()) { + if (m_axisZ) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisZ->min()); int count = int(m_axisZ->max()) - min + 1; - QStringList subList = firstSeries->dataProxy()->rowLabels().mid(min, count); - static_cast<Q3DCategoryAxis *>(m_axisZ)->dptr()->setDataLabels(subList); + QStringList subList; + if (m_primarySeries && m_primarySeries->dataProxy()) + subList = m_primarySeries->dataProxy()->rowLabels().mid(min, count); + static_cast<QCategory3DAxis *>(m_axisZ)->dptr()->setDataLabels(subList); } } void Bars3DController::handleDataColumnLabelsChanged() { - QBar3DSeries *firstSeries = 0; - if (m_seriesList.size()) - firstSeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); - if (m_axisX && firstSeries && firstSeries->dataProxy()) { + if (m_axisX) { // Grab a sublist equal to data window (no need to have more labels in axis) int min = int(m_axisX->min()); int count = int(m_axisX->max()) - min + 1; - QStringList subList = static_cast<QBarDataProxy *>(firstSeries->dataProxy()) - ->columnLabels().mid(min, count); - static_cast<Q3DCategoryAxis *>(m_axisX)->dptr()->setDataLabels(subList); + QStringList subList; + if (m_primarySeries && m_primarySeries->dataProxy()) { + subList = static_cast<QBarDataProxy *>(m_primarySeries->dataProxy()) + ->columnLabels().mid(min, count); + } + static_cast<QCategory3DAxis *>(m_axisX)->dptr()->setDataLabels(subList); } } -void Bars3DController::handleBarClicked(const QPoint &position, QBar3DSeries *series) -{ - setSelectedBar(position, series); - - // TODO: pass clicked to parent. (QTRD-2517) - // TODO: Also hover needed? (QTRD-2131) -} - void Bars3DController::handleAxisAutoAdjustRangeChangedInOrientation( - Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) { Q_UNUSED(orientation) Q_UNUSED(autoAdjust) @@ -203,63 +238,120 @@ void Bars3DController::handleSeriesVisibilityChangedBySender(QObject *sender) { Abstract3DController::handleSeriesVisibilityChangedBySender(sender); + adjustAxisRanges(); + // Visibility changes may require disabling/enabling slicing, // so just reset selection to ensure everything is still valid. setSelectedBar(m_selectedBar, m_selectedBarSeries); } +void Bars3DController::handlePendingClick() +{ + // This function is called while doing the sync, so it is okay to query from renderer + QPoint position = m_renderer->clickedPosition(); + QBar3DSeries *series = static_cast<QBar3DSeries *>(m_renderer->clickedSeries()); + + setSelectedBar(position, series); + + m_renderer->resetClickedStatus(); +} + QPoint Bars3DController::invalidSelectionPosition() { static QPoint invalidSelectionPos(-1, -1); return invalidSelectionPos; } -void Bars3DController::setAxisX(Q3DAbstractAxis *axis) +void Bars3DController::setAxisX(QAbstract3DAxis *axis) { Abstract3DController::setAxisX(axis); handleDataColumnLabelsChanged(); } -void Bars3DController::setAxisZ(Q3DAbstractAxis *axis) +void Bars3DController::setAxisZ(QAbstract3DAxis *axis) { Abstract3DController::setAxisZ(axis); handleDataRowLabelsChanged(); } -void Bars3DController::addSeries(QAbstract3DSeries *series) +void Bars3DController::setPrimarySeries(QBar3DSeries *series) { - Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeBar); - - bool firstAdded = !m_seriesList.size(); - - Abstract3DController::addSeries(series); - - if (firstAdded) { - adjustAxisRanges(); + if (!series) { + if (m_seriesList.size()) + series = static_cast<QBar3DSeries *>(m_seriesList.at(0)); + } else if (!m_seriesList.contains(series)) { + // Add nonexistent series. + addSeries(series); + } + if (m_primarySeries != series) { + m_primarySeries = series; handleDataRowLabelsChanged(); handleDataColumnLabelsChanged(); + emit primarySeriesChanged(m_primarySeries); } +} + +QBar3DSeries *Bars3DController::primarySeries() const +{ + return m_primarySeries; +} - QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series); - if (barSeries->selectedBar() != invalidSelectionPosition()) - setSelectedBar(barSeries->selectedBar(), barSeries); +void Bars3DController::addSeries(QAbstract3DSeries *series) +{ + insertSeries(m_seriesList.size(), series); } void Bars3DController::removeSeries(QAbstract3DSeries *series) { - bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series); + bool wasVisible = (series && series->d_ptr->m_controller == this && series->isVisible()); Abstract3DController::removeSeries(series); if (m_selectedBarSeries == series) setSelectedBar(invalidSelectionPosition(), 0); - if (firstRemoved) { + if (wasVisible) adjustAxisRanges(); + // If primary series is removed, reset it to default + if (series == m_primarySeries) { + if (m_seriesList.size()) + m_primarySeries = static_cast<QBar3DSeries *>(m_seriesList.at(0)); + else + m_primarySeries = 0; + handleDataRowLabelsChanged(); handleDataColumnLabelsChanged(); + + emit primarySeriesChanged(m_primarySeries); + } +} + +void Bars3DController::insertSeries(int index, QAbstract3DSeries *series) +{ + Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeBar); + + int oldSize = m_seriesList.size(); + + Abstract3DController::insertSeries(index, series); + + if (oldSize != m_seriesList.size()) { + if (series->isVisible()) + adjustAxisRanges(); + + QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series); + if (!oldSize) { + m_primarySeries = barSeries; + handleDataRowLabelsChanged(); + handleDataColumnLabelsChanged(); + } + + if (barSeries->selectedBar() != invalidSelectionPosition()) + setSelectedBar(barSeries->selectedBar(), barSeries); + + if (!oldSize) + emit primarySeriesChanged(m_primarySeries); } } @@ -292,6 +384,19 @@ void Bars3DController::handleAxisRangeChangedBySender(QObject *sender) setSelectedBar(m_selectedBar, m_selectedBarSeries); } +void Bars3DController::setMultiSeriesScaling(bool uniform) +{ + m_isMultiSeriesUniform = uniform; + + m_changeTracker.multiSeriesScalingChanged = true; + emitNeedRender(); +} + +bool Bars3DController::multiSeriesScaling() const +{ + return m_isMultiSeriesUniform; +} + void Bars3DController::setBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative) { m_barThicknessRatio = thicknessRatio; @@ -317,13 +422,14 @@ bool Bars3DController::isBarSpecRelative() return m_isBarSpecRelative; } -void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode) +void Bars3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { - if (mode.testFlag(QDataVis::SelectionSlice) - && (mode.testFlag(QDataVis::SelectionRow) == mode.testFlag(QDataVis::SelectionColumn))) { + if (mode.testFlag(QAbstract3DGraph::SelectionSlice) + && (mode.testFlag(QAbstract3DGraph::SelectionRow) + == mode.testFlag(QAbstract3DGraph::SelectionColumn))) { qWarning("Must specify one of either row or column selection mode in conjunction with slicing mode."); } else { - QDataVis::SelectionFlags oldMode = selectionMode(); + QAbstract3DGraph::SelectionFlags oldMode = selectionMode(); Abstract3DController::setSelectionMode(mode); @@ -334,8 +440,8 @@ void Bars3DController::setSelectionMode(QDataVis::SelectionFlags mode) // Special case: Always deactivate slicing when changing away from slice // automanagement, as this can't be handled in setSelectedBar. - if (!mode.testFlag(QDataVis::SelectionSlice) - && oldMode.testFlag(QDataVis::SelectionSlice)) { + if (!mode.testFlag(QAbstract3DGraph::SelectionSlice) + && oldMode.testFlag(QAbstract3DGraph::SelectionSlice)) { scene()->setSlicingActive(false); } } @@ -353,7 +459,7 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri adjustSelectionPosition(pos, series); - if (selectionMode().testFlag(QDataVis::SelectionSlice)) { + if (selectionMode().testFlag(QAbstract3DGraph::SelectionSlice)) { // If the selected bar is outside data window, or there is no visible selected bar, disable slicing if (pos.x() < m_axisZ->min() || pos.x() > m_axisZ->max() || pos.y() < m_axisX->min() || pos.y() > m_axisX->max() @@ -383,11 +489,16 @@ void Bars3DController::setSelectedBar(const QPoint &position, QBar3DSeries *seri } } +void Bars3DController::clearSelection() +{ + setSelectedBar(invalidSelectionPosition(), 0); +} + void Bars3DController::adjustAxisRanges() { - Q3DCategoryAxis *categoryAxisZ = static_cast<Q3DCategoryAxis *>(m_axisZ); - Q3DCategoryAxis *categoryAxisX = static_cast<Q3DCategoryAxis *>(m_axisX); - Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisY); + QCategory3DAxis *categoryAxisZ = static_cast<QCategory3DAxis *>(m_axisZ); + QCategory3DAxis *categoryAxisX = static_cast<QCategory3DAxis *>(m_axisX); + QValue3DAxis *valueAxis = static_cast<QValue3DAxis *>(m_axisY); bool adjustZ = (categoryAxisZ && categoryAxisZ->isAutoAdjustRange()); bool adjustX = (categoryAxisX && categoryAxisX->isAutoAdjustRange()); @@ -493,11 +604,11 @@ void Bars3DController::adjustSelectionPosition(QPoint &pos, const QBar3DSeries * } } -Q3DAbstractAxis *Bars3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation) +QAbstract3DAxis *Bars3DController::createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation) { - Q3DAbstractAxis *defaultAxis = 0; + QAbstract3DAxis *defaultAxis = 0; - if (orientation == Q3DAbstractAxis::AxisOrientationY) + if (orientation == QAbstract3DAxis::AxisOrientationY) defaultAxis = createDefaultValueAxis(); else defaultAxis = createDefaultCategoryAxis(); @@ -505,4 +616,4 @@ Q3DAbstractAxis *Bars3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrient return defaultAxis; } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h index 54385571..e704aea1 100644 --- a/src/datavisualization/engine/bars3dcontroller_p.h +++ b/src/datavisualization/engine/bars3dcontroller_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,20 +32,20 @@ #include "datavisualizationglobal_p.h" #include "abstract3dcontroller_p.h" -//#define DISPLAY_RENDER_SPEED - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Bars3DRenderer; class QBar3DSeries; struct Bars3DChangeBitField { - bool slicingActiveChanged : 1; - bool barSpecsChanged : 1; - bool selectedBarChanged : 1; + bool slicingActiveChanged : 1; + bool multiSeriesScalingChanged : 1; + bool barSpecsChanged : 1; + bool selectedBarChanged : 1; Bars3DChangeBitField() : slicingActiveChanged(true), + multiSeriesScalingChanged(true), barSpecsChanged(true), selectedBarChanged(true) { @@ -63,8 +63,10 @@ private: QPoint m_selectedBar; // Points to row & column in data window. QBar3DSeries *m_selectedBarSeries; // Points to the series for which the bar is selected in // single series selection cases. + QBar3DSeries *m_primarySeries; // Category axis labels are taken from the primary series // Look'n'feel + bool m_isMultiSeriesUniform; bool m_isBarSpecRelative; GLfloat m_barThicknessRatio; QSizeF m_barSpacing; @@ -73,12 +75,15 @@ private: Bars3DRenderer *m_renderer; public: - explicit Bars3DController(QRect rect); + explicit Bars3DController(QRect rect, Q3DScene *scene = 0); ~Bars3DController(); virtual void initializeOpenGL(); virtual void synchDataToRenderer(); + void setMultiSeriesScaling(bool uniform); + bool multiSeriesScaling() const; + // bar thickness, spacing between bars, and is spacing relative to thickness or absolute // y -component sets the thickness/spacing of z -direction // With relative 0.0f means side-to-side, 1.0f = one thickness in between @@ -89,19 +94,24 @@ public: QSizeF barSpacing(); bool isBarSpecRelative(); - void setSelectionMode(QDataVis::SelectionFlags mode); + void setSelectionMode(QAbstract3DGraph::SelectionFlags mode); void setSelectedBar(const QPoint &position, QBar3DSeries *series); + virtual void clearSelection(); - virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); + virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); + virtual void handlePendingClick(); static QPoint invalidSelectionPosition(); - virtual void setAxisX(Q3DAbstractAxis *axis); - virtual void setAxisZ(Q3DAbstractAxis *axis); + virtual void setAxisX(QAbstract3DAxis *axis); + virtual void setAxisZ(QAbstract3DAxis *axis); + virtual void setPrimarySeries(QBar3DSeries *series); + virtual QBar3DSeries *primarySeries() const; virtual void addSeries(QAbstract3DSeries *series); virtual void removeSeries(QAbstract3DSeries *series); + virtual void insertSeries(int index, QAbstract3DSeries *series); virtual QList<QBar3DSeries *> barSeriesList(); virtual void handleAxisRangeChangedBySender(QObject *sender); @@ -116,11 +126,11 @@ public slots: void handleDataRowLabelsChanged(); void handleDataColumnLabelsChanged(); - // Renderer callback handlers - void handleBarClicked(const QPoint &position, QBar3DSeries *series); +signals: + void primarySeriesChanged(QBar3DSeries *series); protected: - virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation); + virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation); private: void adjustAxisRanges(); @@ -130,7 +140,6 @@ private: }; - -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index f13b6e79..664dbabd 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -38,12 +38,13 @@ // You should see the scene from where the light is //#define SHOW_DEPTH_TEXTURE_SCENE -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION const GLfloat labelMargin = 0.05f; const GLfloat gridLineWidth = 0.005f; -const bool sliceGridLabels = true; // TODO: Make this user controllable (QTRD-2546) +const bool sliceGridLabels = true; +const QQuaternion identityQuaternion; Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) : Abstract3DRenderer(controller), @@ -89,9 +90,12 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_selectedBarPos(Bars3DController::invalidSelectionPosition()), m_selectedBarSeries(0), m_noZeroInRange(false), - m_seriesScale(0.0f), + m_seriesScaleX(0.0f), + m_seriesScaleZ(0.0f), m_seriesStep(0.0f), - m_seriesStart(0.0f) + m_seriesStart(0.0f), + m_clickedPosition(Bars3DController::invalidSelectionPosition()), + m_keepSeriesUniform(false) { initializeOpenGLFunctions(); initializeOpenGL(); @@ -159,11 +163,17 @@ void Bars3DRenderer::updateData() if (m_renderingArrays.size() != seriesCount) { m_renderingArrays.resize(seriesCount); - m_seriesScale = 1.0f / float(seriesCount); + m_seriesScaleX = 1.0f / float(seriesCount); m_seriesStep = 1.0f / float(seriesCount); m_seriesStart = -((float(seriesCount) - 1.0f) / 2.0f) * m_seriesStep; } + + if (m_keepSeriesUniform) + m_seriesScaleZ = m_seriesScaleX; + else + m_seriesScaleZ = 1.0f; + if (m_cachedRowCount != newRows || m_cachedColumnCount != newColumns) { // Force update for selection related items m_sliceCache = 0; @@ -181,12 +191,13 @@ void Bars3DRenderer::updateData() } for (int series = 0; series < seriesCount; series++) { - if (newRows != m_renderingArrays.at(series).size() - || newColumns != m_renderingArrays.at(series).at(0).size()) { + BarRenderItemArray &renderArray = m_renderingArrays[series]; + if (newRows != renderArray.size() + || newColumns != renderArray.at(0).size()) { // Destroy old render items and reallocate new array - m_renderingArrays[series].resize(newRows); + renderArray.resize(newRows); for (int i = 0; i < newRows; i++) - m_renderingArrays[series][i].resize(newColumns); + renderArray[i].resize(newColumns); } // Update cached data window @@ -199,10 +210,10 @@ void Bars3DRenderer::updateData() GLfloat heightValue = 0.0f; for (int i = 0; i < newRows; i++) { int j = 0; + BarRenderItemRow &renderRow = renderArray[i]; if (dataRowIndex < dataRowCount) { const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex); - updateSize = qMin((dataRow->size() - minCol), - m_renderingArrays.at(series).at(i).size()); + updateSize = qMin((dataRow->size() - minCol), renderRow.size()); if (dataRow) { int dataColIndex = minCol; for (; j < updateSize ; j++) { @@ -221,15 +232,24 @@ void Bars3DRenderer::updateData() heightValue = 0.0f; } } - m_renderingArrays[series][i][j].setValue(value); - m_renderingArrays[series][i][j].setHeight(heightValue / m_heightNormalizer); + renderRow[j].setValue(value); + renderRow[j].setHeight(heightValue / m_heightNormalizer); + float angle = dataRow->at(dataColIndex).rotation(); + if (angle) { + renderRow[j].setRotation( + QQuaternion::fromAxisAndAngle( + upVector, angle)); + } else { + renderRow[j].setRotation(identityQuaternion); + } dataColIndex++; } } } for (; j < m_renderingArrays.at(series).at(i).size(); j++) { - m_renderingArrays[series][i][j].setValue(0.0f); - m_renderingArrays[series][i][j].setHeight(0.0f); + renderRow[j].setValue(0.0f); + renderRow[j].setHeight(0.0f); + renderRow[j].setRotation(identityQuaternion); } dataRowIndex++; } @@ -239,9 +259,20 @@ void Bars3DRenderer::updateData() updateSelectedBar(m_selectedBarPos, m_selectedBarSeries); } +void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility) +{ + Abstract3DRenderer::updateSeries(seriesList, updateVisibility); + + // Fix the series rotations - ignore any rotations that are not along Y-axis + for (int series = 0; series < m_visibleSeriesList.size(); series++) { + QVector3D vector = m_visibleSeriesList.at(series).meshRotation().vector(); + if (vector.x() || vector.z()) + m_visibleSeriesList[series].setMeshRotation(identityQuaternion); + } +} + void Bars3DRenderer::updateScene(Q3DScene *scene) { - // TODO: See QTRD-2374 if (m_hasNegativeValues) scene->activeCamera()->setMinYRotation(-90.0); else @@ -274,6 +305,8 @@ void Bars3DRenderer::drawSlicedScene() { GLfloat barPosX = 0; QVector3D lightPos; + QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); + static QQuaternion ninetyDegreeRotation = QQuaternion::fromAxisAndAngle(upVector, 90.0f); // Specify viewport glViewport(m_secondarySubViewport.x(), @@ -283,7 +316,7 @@ void Bars3DRenderer::drawSlicedScene() // Set up projection matrix QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(40.0f, (GLfloat)m_secondarySubViewport.width() + projectionMatrix.perspective(35.0f, (GLfloat)m_secondarySubViewport.width() / (GLfloat)m_secondarySubViewport.height(), 0.1f, 100.0f); // Set view matrix @@ -300,16 +333,18 @@ void Bars3DRenderer::drawSlicedScene() const Q3DCamera *activeCamera = m_cachedScene->activeCamera(); // Draw the selected row / column - GLfloat barPosYAdjustment = -0.8f; // Positives only -> translate to -1.0 + 0.2 for row/column labels - if (m_hasNegativeValues) { - if (m_noZeroInRange) - barPosYAdjustment = 1.2f; // Negatives only -> translate to 1.0 + 0.2 for row/column labels - else - barPosYAdjustment = 0.2f; // Both -> translate to 0.0 + 0.2 for row/column labels - } QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; - bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow); - bool itemMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionItem); + bool rowMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow); + bool itemMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem); + + GLfloat barPosYAdjustment = -0.8f; // Translate to -1.0 + 0.2 for row/column labels + GLfloat scaleFactor = 0.0f; + GLfloat barLabelYPos = barPosYAdjustment - 0.4f - labelMargin; // 0.4 for labels + GLfloat zeroPosAdjustment = 0.0f; + if (!m_noZeroInRange) + zeroPosAdjustment = 2.0f * m_axisCacheY.min() / m_heightNormalizer; + else if (m_hasNegativeValues) + zeroPosAdjustment = -2.0f; // Draw grid lines if (m_cachedTheme->isGridEnabled()) { @@ -323,24 +358,20 @@ void Bars3DRenderer::drawSlicedScene() lineShader->setUniformValue(lineShader->lightP(), lightPos); lineShader->setUniformValue(lineShader->view(), viewMatrix); lineShader->setUniformValue(lineShader->color(), lineColor); - lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength() * 2.0f); - lineShader->setUniformValue(lineShader->lightS(), 0.25f); + lineShader->setUniformValue(lineShader->ambientS(), + m_cachedTheme->ambientLightStrength() * 2.3f); + lineShader->setUniformValue(lineShader->lightS(), 0.0f); + lineShader->setUniformValue(lineShader->lightColor(), lightColor); - GLfloat scaleFactor = 0.0f; if (rowMode) scaleFactor = (1.1f * m_rowWidth) / m_scaleFactor; else scaleFactor = (1.1f * m_columnDepth) / m_scaleFactor; - GLfloat startLine = 0.0f; - if (m_noZeroInRange) - startLine = 2.0f * (m_axisCacheY.min() - m_axisCacheY.max()) / m_heightNormalizer; - else - startLine = 2.0f * m_axisCacheY.min() / m_heightNormalizer; - GLfloat gridStep = (2.0f * m_axisCacheY.subSegmentStep()) / m_heightNormalizer; - GLfloat gridPos = startLine + barPosYAdjustment; + GLfloat gridPos = barPosYAdjustment; int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount(); + // Use the position of the bottom grid line as the base y position for bar labels // Horizontal lines if (m_axisCacheY.segmentCount() > 0) { @@ -365,7 +396,8 @@ void Bars3DRenderer::drawSlicedScene() // Draw the object m_drawer->drawObject(lineShader, m_gridLineObj); - if (gridPos == barPosYAdjustment) + // Check if we have a line at zero position already + if (gridPos == (barPosYAdjustment + zeroPosAdjustment)) noZero = false; gridPos += gridStep; @@ -373,7 +405,7 @@ void Bars3DRenderer::drawSlicedScene() // Draw a line at zero, if none exists if (!m_noZeroInRange && noZero) { QMatrix4x4 modelMatrix; - modelMatrix.translate(0.0f, barPosYAdjustment, 0.0f); + modelMatrix.translate(0.0f, barPosYAdjustment - zeroPosAdjustment, 0.0f); modelMatrix.scale(gridLineScale); itModelMatrix = modelMatrix; MVPMatrix = projectionViewMatrix * modelMatrix; @@ -391,7 +423,6 @@ void Bars3DRenderer::drawSlicedScene() } } - // TODO: Make user controllable (QTRD-2546) if (sliceGridLabels) { // Bind label shader m_labelShader->bind(); @@ -404,7 +435,7 @@ void Bars3DRenderer::drawSlicedScene() int labelNbr = 0; int labelCount = m_axisCacheY.labels().size(); gridStep = (2.0f * m_axisCacheY.segmentStep()) / m_heightNormalizer; - gridPos = startLine + barPosYAdjustment; + gridPos = barPosYAdjustment; QVector3D backLabelRotation(0.0f, 0.0f, 0.0f); QVector3D labelTrans = QVector3D(scaleFactor + labelMargin, 0.0f, 0.0f); @@ -428,26 +459,28 @@ void Bars3DRenderer::drawSlicedScene() } // Draw bars - QVector3D modelMatrixScaler(m_scaleX, 0.0f, m_scaleZ); - if (rowMode) - modelMatrixScaler.setX(m_scaleX * m_seriesScale); - else - modelMatrixScaler.setZ(m_scaleZ * m_seriesScale); + QVector3D modelMatrixScaler(m_scaleX * m_seriesScaleX, 0.0f, m_scaleZ * m_seriesScaleZ); + if (!rowMode) { + modelMatrixScaler.setX(m_scaleZ * m_seriesScaleZ); + modelMatrixScaler.setZ(m_scaleX * m_seriesScaleX); + } // Set common bar shader bindings m_barShader->bind(); m_barShader->setUniformValue(m_barShader->lightP(), lightPos); m_barShader->setUniformValue(m_barShader->view(), viewMatrix); - m_barShader->setUniformValue(m_barShader->lightS(), 0.5f); + m_barShader->setUniformValue(m_barShader->lightS(), 0.15f); m_barShader->setUniformValue(m_barShader->ambientS(), - m_cachedTheme->ambientLightStrength() * 2.0f); + m_cachedTheme->ambientLightStrength() * 2.3f); + m_barShader->setUniformValue(m_barShader->lightColor(), lightColor); m_barGradientShader->bind(); m_barGradientShader->setUniformValue(m_barGradientShader->lightP(), lightPos); m_barGradientShader->setUniformValue(m_barGradientShader->view(), viewMatrix); - m_barGradientShader->setUniformValue(m_barGradientShader->lightS(), 0.5f); + m_barGradientShader->setUniformValue(m_barGradientShader->lightS(), 0.15f); m_barGradientShader->setUniformValue(m_barGradientShader->ambientS(), - m_cachedTheme->ambientLightStrength() * 2.0f); + m_cachedTheme->ambientLightStrength() * 2.3f); m_barGradientShader->setUniformValue(m_barGradientShader->gradientMin(), 0.0f); + m_barGradientShader->setUniformValue(m_barGradientShader->lightColor(), lightColor); // Default to uniform shader ShaderHelper *barShader = m_barShader; @@ -457,10 +490,10 @@ void Bars3DRenderer::drawSlicedScene() Q3DTheme::ColorStyle previousColorStyle = Q3DTheme::ColorStyleUniform; Q3DTheme::ColorStyle colorStyle = Q3DTheme::ColorStyleUniform; ObjectHelper *barObj = 0; - QVector3D barHighlightColor; - QVector3D rowHighlightColor; - GLuint barGradientTexture = 0; - GLuint rowGradientTexture = 0; + QVector3D highlightColor; + QVector3D baseColor; + GLuint highlightGradientTexture = 0; + GLuint baseGradientTexture = 0; const SeriesRenderCache *currentSeries = 0; bool colorStyleIsUniform = true; @@ -470,6 +503,8 @@ void Bars3DRenderer::drawSlicedScene() if (!item) continue; + QQuaternion seriesRotation; + if (item->seriesIndex() != currentSeriesIndex) { currentSeriesIndex = item->seriesIndex(); currentSeries = &(m_visibleSeriesList.at(currentSeriesIndex)); @@ -477,11 +512,11 @@ void Bars3DRenderer::drawSlicedScene() colorStyle = currentSeries->colorStyle(); colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform); if (colorStyleIsUniform) { - barHighlightColor = currentSeries->singleHighlightColor(); - rowHighlightColor = currentSeries->multiHighlightColor(); + highlightColor = currentSeries->singleHighlightColor(); + baseColor = currentSeries->baseColor(); } else { - barGradientTexture = currentSeries->singleHighlightGradientTexture(); - rowGradientTexture = currentSeries->multiHighlightGradientTexture(); + highlightGradientTexture = currentSeries->singleHighlightGradientTexture(); + baseGradientTexture = currentSeries->baseGradientTexture(); } // Rebind shader if it has changed @@ -500,6 +535,7 @@ void Bars3DRenderer::drawSlicedScene() } previousColorStyle = colorStyle; + seriesRotation = currentSeries->meshRotation(); } if (item->height() < 0) @@ -510,20 +546,27 @@ void Bars3DRenderer::drawSlicedScene() QMatrix4x4 MVPMatrix; QMatrix4x4 modelMatrix; QMatrix4x4 itModelMatrix; - GLfloat barRotation = 0.0f; - GLfloat barPosY = item->translation().y() + barPosYAdjustment; + QQuaternion barRotation = item->rotation(); + GLfloat barPosY = item->translation().y() + barPosYAdjustment - zeroPosAdjustment; if (rowMode) { barPosX = item->translation().x(); } else { barPosX = -(item->translation().z()); // flip z; frontmost bar to the left - barRotation = 90.0f; + barRotation *= ninetyDegreeRotation; } modelMatrix.translate(barPosX, barPosY, 0.0f); modelMatrixScaler.setY(item->height()); - modelMatrix.rotate(barRotation, 0.0f, 1.0f, 0.0f); - itModelMatrix.rotate(barRotation, 0.0f, 1.0f, 0.0f); + + if (!seriesRotation.isIdentity()) + barRotation *= seriesRotation; + + if (!barRotation.isIdentity()) { + modelMatrix.rotate(barRotation); + itModelMatrix.rotate(barRotation); + } + modelMatrix.scale(modelMatrixScaler); itModelMatrix.scale(modelMatrixScaler); @@ -535,14 +578,14 @@ void Bars3DRenderer::drawSlicedScene() if (itemMode && m_visualSelectedBarPos.x() == item->position().x() && m_visualSelectedBarPos.y() == item->position().y()) { if (colorStyleIsUniform) - barColor = barHighlightColor; + barColor = highlightColor; else - gradientTexture = barGradientTexture; + gradientTexture = highlightGradientTexture; } else { if (colorStyleIsUniform) - barColor = rowHighlightColor; + barColor = baseColor; else - gradientTexture = rowGradientTexture; + gradientTexture = baseGradientTexture; } if (item->height() != 0) { @@ -578,66 +621,79 @@ void Bars3DRenderer::drawSlicedScene() QVector3D positionComp(0.0f, m_autoScaleAdjustment, 0.0f); // Draw labels for bars - QVector3D valuePositionComp = zeroVector; - if (!m_hasNegativeValues) - valuePositionComp.setY(2.0f); - else if (m_noZeroInRange) - valuePositionComp.setY(-2.0f); QVector3D sliceValueRotation(0.0f, 0.0f, 90.0f); QVector3D sliceLabelRotation(0.0f, 0.0f, -45.0f); + int lastLabel = m_sliceCache->labelItems().size() - 1; + + for (int labelNo = 0; labelNo <= lastLabel; labelNo++) { + // Get labels from first series only + BarRenderItem *item = m_sliceSelection.at(labelNo); + m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(), + barLabelYPos, + item->translation().z())); + // Draw labels + m_drawer->drawLabel(m_dummyBarRenderItem, *m_sliceCache->labelItems().at(labelNo), + viewMatrix, projectionMatrix, positionComp, sliceLabelRotation, + 0, m_cachedSelectionMode, m_labelShader, + m_labelObj, activeCamera, false, false, Drawer::LabelMid, + Qt::AlignRight, true); + } + for (int col = 0; col < sliceItemCount; col++) { BarRenderItem *item = m_sliceSelection.at(col); - // TODO: Make user controllable (QTRD-2546) if (!sliceGridLabels) { // Draw values if (item->height() != 0.0f || (!m_noZeroInRange && item->value() == 0.0f)) { // Create label texture if we need it - if (item->sliceLabel().isNull()) { - item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), item->value())); + if (item->sliceLabel().isNull() || m_updateLabels) { + item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), + item->value())); m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel()); + m_updateLabels = false; } - m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix, - valuePositionComp, sliceValueRotation, item->height(), - m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, - false, false, Drawer::LabelOver, Qt::AlignTop, true); + Qt::AlignmentFlag alignment = (item->height() < 0) ? Qt::AlignBottom : Qt::AlignTop; + Drawer::LabelPosition labelPos = (item->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver; + m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(), + barPosYAdjustment - zeroPosAdjustment + + item->height(), + item->translation().z())); + + m_drawer->drawLabel(m_dummyBarRenderItem, item->sliceLabelItem(), viewMatrix, + projectionMatrix, zeroVector, sliceValueRotation, + item->height(), m_cachedSelectionMode, m_labelShader, + m_labelObj, activeCamera, false, false, labelPos, + alignment, true); } } else { // Only draw value for selected item when grid labels are on - // TODO: Maybe use selection label instead of value? Should it be user controllable - // as well? (QTRD-2546) if (itemMode && m_visualSelectedBarPos.x() == item->position().x() && m_visualSelectedBarPos.y() == item->position().y() && item->seriesIndex() == m_visualSelectedBarSeriesIndex) { // Create label texture if we need it - if (item->sliceLabel().isNull()) { - item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), item->value())); + if (item->sliceLabel().isNull() || m_updateLabels) { + item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), + item->value())); m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel()); + m_updateLabels = false; } - m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix, - valuePositionComp, sliceValueRotation, item->height(), - m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, - false, false, Drawer::LabelOver, Qt::AlignTop, true); + Qt::AlignmentFlag alignment = (item->height() < 0) ? Qt::AlignBottom : Qt::AlignTop; + Drawer::LabelPosition labelPos = (item->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver; + m_dummyBarRenderItem.setTranslation(QVector3D(item->translation().x(), + barPosYAdjustment - zeroPosAdjustment + + item->height(), + item->translation().z())); + + m_drawer->drawLabel(m_dummyBarRenderItem, item->sliceLabelItem(), viewMatrix, + projectionMatrix, zeroVector, sliceValueRotation, + item->height(), m_cachedSelectionMode, m_labelShader, + m_labelObj, activeCamera, false, false, labelPos, + alignment, true); } } } - int lastLabel = m_sliceCache->labelItems().size() - 1; - - for (int labelNo = 0; labelNo <= lastLabel; labelNo++) { - // Get labels from first series only - BarRenderItem *item = m_sliceSelection.at(labelNo); - // TODO: Make user controllable (QTRD-2546) - // Draw labels - m_drawer->drawLabel(*item, *m_sliceCache->labelItems().at(labelNo), viewMatrix, - projectionMatrix, positionComp, sliceLabelRotation, - item->height(), m_cachedSelectionMode, m_labelShader, - m_labelObj, activeCamera, false, false, Drawer::LabelBelow, - Qt::AlignCenter, true); - } - - // TODO: Make user controllable (QTRD-2546) // Draw labels for axes if (rowMode) { if (m_sliceTitleItem) { @@ -662,10 +718,13 @@ void Bars3DRenderer::drawSlicedScene() Qt::AlignCenter, true); } } - m_drawer->drawLabel(*dummyItem, m_axisCacheY.titleItem(), viewMatrix, projectionMatrix, - positionComp, QVector3D(0.0f, 0.0f, 90.0f), 0, + // Y-axis label + QVector3D labelTrans = QVector3D(-scaleFactor - labelMargin, 0.2f, 0.0f); // y = 0.2 for row/column labels (see barPosYAdjustment) + m_dummyBarRenderItem.setTranslation(labelTrans); + m_drawer->drawLabel(m_dummyBarRenderItem, m_axisCacheY.titleItem(), viewMatrix, + projectionMatrix, zeroVector, QVector3D(0.0f, 0.0f, 90.0f), 0, m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, - false, false, Drawer::LabelLeft, Qt::AlignCenter, true); + false, false, Drawer::LabelMid, Qt::AlignHCenter); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); @@ -690,6 +749,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) GLfloat colPos = 0; GLfloat rowPos = 0; + QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); + int seriesCount = m_visibleSeriesList.size(); const Q3DCamera *activeCamera = m_cachedScene->activeCamera(); @@ -701,7 +762,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Set up projection matrix QMatrix4x4 projectionMatrix; - GLfloat viewPortRatio = (GLfloat)m_primarySubViewport.width() / (GLfloat)m_primarySubViewport.height(); + GLfloat viewPortRatio = (GLfloat)m_primarySubViewport.width() + / (GLfloat)m_primarySubViewport.height(); projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f); // Get the view matrix @@ -760,10 +822,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; - bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow); + bool rowMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Render scene into a depth texture for using with shadow mapping // Enable drawing to depth framebuffer glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer); @@ -784,19 +846,17 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) zeroVector, 0.0f, 3.5f / m_autoScaleAdjustment); depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector); - // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? - // That causes the scene to be not drawn from above -> must be fixed - // qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); - // Set the depth projection matrix depthProjectionMatrix.perspective(10.0f, viewPortRatio, 3.0f, 100.0f); depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix; // Draw bars to depth buffer - QVector3D shadowScaler(m_scaleX * m_seriesScale * 0.9f, 0.0f, m_scaleZ * 0.9f); + QVector3D shadowScaler(m_scaleX * m_seriesScaleX * 0.9f, 0.0f, + m_scaleZ * m_seriesScaleZ * 0.9f); float seriesPos = m_seriesStart; for (int series = 0; series < seriesCount; series++) { ObjectHelper *barObj = m_visibleSeriesList.at(series).object(); + QQuaternion seriesRotation(m_visibleSeriesList.at(series).meshRotation()); for (int row = startRow; row != stopRow; row += stepRow) { for (int bar = startBar; bar != stopBar; bar += stepBar) { GLfloat shadowOffset = 0.0f; @@ -828,6 +888,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) (m_columnDepth - rowPos) / m_scaleFactor); // Scale the bars down in X and Z to reduce self-shadowing issues shadowScaler.setY(item.height()); + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) + modelMatrix.rotate(seriesRotation * item.rotation()); modelMatrix.scale(shadowScaler); MVPMatrix = depthProjectionViewMatrix * modelMatrix; @@ -860,19 +922,6 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Disable drawing to depth framebuffer (= enable drawing to screen) glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); -#if 0 // Use this if you want to see what is being drawn to the framebuffer - // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it) - m_labelShader->bind(); - glCullFace(GL_BACK); - glEnable(GL_TEXTURE_2D); - QMatrix4x4 modelMatrix; - QMatrix4x4 viewmatrix; - viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f), zeroVector, upVector); - QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; - m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix); - m_drawer->drawObject(m_labelShader, m_labelObj, m_depthTexture); - glDisable(GL_TEXTURE_2D); -#endif // Reset culling to normal glCullFace(GL_BACK); @@ -884,9 +933,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } #endif - // TODO: Selection must be enabled currently to support clicked signal. (QTRD-2517) // Skip selection mode drawing if we're slicing or have no selection mode - if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::SelectionNone + if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone && m_selectionState == SelectOnScene && seriesCount > 0) { // Bind selection shader m_selectionShader->bind(); @@ -904,6 +952,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) float seriesPos = m_seriesStart; for (int series = 0; series < seriesCount; series++) { ObjectHelper *barObj = m_visibleSeriesList.at(series).object(); + QQuaternion seriesRotation(m_visibleSeriesList.at(series).meshRotation()); for (int row = startRow; row != stopRow; row += stepRow) { for (int bar = startBar; bar != stopBar; bar += stepBar) { const BarRenderItem &item = m_renderingArrays.at(series).at(row).at(bar); @@ -924,21 +973,17 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor, item.height(), (m_columnDepth - rowPos) / m_scaleFactor); - modelMatrix.scale(QVector3D(m_scaleX * m_seriesScale, + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) + modelMatrix.rotate(seriesRotation * item.rotation()); + modelMatrix.scale(QVector3D(m_scaleX * m_seriesScaleX, item.height(), - m_scaleZ)); + m_scaleZ * m_seriesScaleZ)); MVPMatrix = projectionViewMatrix * modelMatrix; - //#if !defined(QT_OPENGL_ES_2) - // QVector3D barColor = QVector3D(GLfloat(row) / 32767.0f, - // GLfloat(bar) / 32767.0f, - // 0.0f); - //#else QVector3D barColor = QVector3D(GLfloat(row) / 255.0f, GLfloat(bar) / 255.0f, GLfloat(series) / 255.0f); - //#endif m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix); m_selectionShader->setUniformValue(m_selectionShader->color(), barColor); @@ -970,7 +1015,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Read color under cursor QVector3D clickedColor = Utils::getSelection(m_inputPosition, m_viewport.height()); - emit barClicked(selectionColorToArrayPosition(clickedColor), selectionColorToSeries(clickedColor)); + m_clickedPosition = selectionColorToArrayPosition(clickedColor); + m_clickedSeries = selectionColorToSeries(clickedColor); + + emit needRender(); // Revert to original render target and viewport glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); @@ -1004,6 +1052,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_barGradientShader->setUniformValue(m_barGradientShader->ambientS(), m_cachedTheme->ambientLightStrength()); m_barGradientShader->setUniformValue(m_barGradientShader->gradientMin(), 0.0f); + m_barGradientShader->setUniformValue(m_barGradientShader->lightColor(), lightColor); } if (haveUniformColorSeries) { @@ -1012,6 +1061,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_barShader->setUniformValue(m_barShader->view(), viewMatrix); m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme->ambientLightStrength()); + m_barShader->setUniformValue(m_barShader->lightColor(), lightColor); barShader = m_barShader; } else { barShader = m_barGradientShader; @@ -1026,7 +1076,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) reserveAmount = m_cachedColumnCount; else reserveAmount = m_cachedRowCount; - if (m_cachedSelectionMode.testFlag(QDataVis::SelectionMultiSeries)) + if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) reserveAmount *= m_visibleSeriesList.size(); m_sliceSelection.resize(reserveAmount); @@ -1048,11 +1098,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) QVector3D baseColor; QVector3D barColor; - QVector3D modelScaler(m_scaleX * m_seriesScale, 0.0f, m_scaleZ); + QVector3D modelScaler(m_scaleX * m_seriesScaleX, 0.0f, m_scaleZ * m_seriesScaleZ); bool somethingSelected = (m_visualSelectedBarPos != Bars3DController::invalidSelectionPosition()); float seriesPos = m_seriesStart; for (int series = 0; series < seriesCount; series++) { const SeriesRenderCache ¤tSeries = m_visibleSeriesList.at(series); + QQuaternion seriesRotation(currentSeries.meshRotation()); ObjectHelper *barObj = currentSeries.object(); Q3DTheme::ColorStyle colorStyle = currentSeries.colorStyle(); bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform); @@ -1074,7 +1125,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } // Always use base color when no selection mode - if (m_cachedSelectionMode == QDataVis::SelectionNone) { + if (m_cachedSelectionMode == QAbstract3DGraph::SelectionNone) { if (colorStyleIsUniform) barColor = baseColor; else @@ -1085,7 +1136,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) int sliceSeriesAdjust = 0; if (m_selectionDirty && m_cachedIsSlicingActivated) { int seriesMultiplier = 0; - if (m_cachedSelectionMode.testFlag(QDataVis::SelectionMultiSeries)) + if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries)) seriesMultiplier = series; if (rowMode) sliceSeriesAdjust = seriesMultiplier * m_cachedColumnCount; @@ -1113,6 +1164,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) item.height(), (m_columnDepth - rowPos) / m_scaleFactor); modelScaler.setY(item.height()); + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) { + QQuaternion totalRotation = seriesRotation * item.rotation(); + modelMatrix.rotate(totalRotation); + itModelMatrix.rotate(totalRotation); + } modelMatrix.scale(modelScaler); itModelMatrix.scale(modelScaler); #ifdef SHOW_DEPTH_TEXTURE_SCENE @@ -1123,7 +1179,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) GLfloat lightStrength = m_cachedTheme->lightStrength(); GLfloat shadowLightStrength = adjustedLightStrength; - if (m_cachedSelectionMode > QDataVis::SelectionNone) { + if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone) { Bars3DController::SelectionType selectionType = Bars3DController::SelectionNone; if (somethingSelected) selectionType = isSelected(row, bar, series); @@ -1138,7 +1194,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lightStrength = m_cachedTheme->highlightLightStrength(); shadowLightStrength = adjustedHighlightStrength; // Insert position data into render item. We have no ownership, don't delete the previous one - if (!m_cachedIsSlicingActivated && m_visualSelectedBarSeriesIndex == series) { + if (!m_cachedIsSlicingActivated + && m_visualSelectedBarSeriesIndex == series) { selectedBar = &item; selectedBar->setPosition(QPoint(row, bar)); item.setTranslation(modelMatrix.column(3).toVector3D()); @@ -1146,7 +1203,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } if (m_selectionDirty && m_cachedIsSlicingActivated) { QVector3D translation = modelMatrix.column(3).toVector3D(); - if (m_cachedSelectionMode & QDataVis::SelectionColumn + if (m_cachedSelectionMode & QAbstract3DGraph::SelectionColumn && seriesCount > 1) { translation.setZ((m_columnDepth - ((row + 0.5f + seriesPos) * (m_cachedBarSpacing.height()))) @@ -1236,12 +1293,13 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) } #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; barShader->setUniformValue(barShader->shadowQ(), m_shadowQualityToShader); barShader->setUniformValue(barShader->depth(), depthMVPMatrix); barShader->setUniformValue(barShader->lightS(), shadowLightStrength); + barShader->setUniformValue(barShader->lightColor(), lightColor); // Draw the object m_drawer->drawObject(barShader, barObj, gradientTexture, m_depthTexture); @@ -1304,9 +1362,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor); m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(), m_cachedTheme->ambientLightStrength() * 2.0f); + m_backgroundShader->setUniformValue(m_backgroundShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), @@ -1354,7 +1413,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix); @@ -1375,7 +1434,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) // Draw grid lines if (m_cachedTheme->isGridEnabled() && m_heightNormalizer) { ShaderHelper *lineShader = m_backgroundShader; - QQuaternion lineRotation = QQuaternion(); + QQuaternion lineRotation; // Bind bar shader lineShader->bind(); @@ -1386,8 +1445,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->view(), viewMatrix); lineShader->setUniformValue(lineShader->color(), barColor); lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength()); + lineShader->setUniformValue(lineShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadowed shader bindings lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->lightS(), @@ -1396,7 +1456,8 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) #endif { // Set shadowless shader bindings - lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme->lightStrength() / 2.5f); + lineShader->setUniformValue(lineShader->lightS(), + m_cachedTheme->lightStrength() / 2.5f); } GLfloat yFloorLinePosition = 0.0f; @@ -1435,7 +1496,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1473,7 +1534,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1530,7 +1591,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1579,7 +1640,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1625,7 +1686,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) for (int row = 0; row != m_cachedRowCount; row++) { if (m_axisCacheZ.labelItems().size() > row) { // Go through all rows and get position of max+1 or min-1 column, depending on x flip - // We need only positions for them, labels have already been generated at QDataSetPrivate. Just add LabelItems + // We need only positions for them, labels have already been generated rowPos = (row + 0.5f) * m_cachedBarSpacing.height(); if (m_xFlipped) colPos = -colPosValue; @@ -1662,7 +1723,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) for (int column = 0; column != m_cachedColumnCount; column++) { if (m_axisCacheX.labelItems().size() > column) { // Go through all columns and get position of max+1 or min-1 row, depending on z flip - // We need only positions for them, labels have already been generated at QDataSetPrivate. Just add LabelItems + // We need only positions for them, labels have already been generated colPos = (column + 0.5f) * m_cachedBarSpacing.width(); if (m_zFlipped) rowPos = -rowPosValue; @@ -1756,9 +1817,10 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) glDisable(GL_DEPTH_TEST); // Draw the selection label LabelItem &labelItem = selectedBar->selectionLabelItem(); - if (m_selectedBar != selectedBar || m_updateLabels || !labelItem.textureId()) { + if (m_selectedBar != selectedBar || m_updateLabels || !labelItem.textureId() + || m_selectionLabelDirty) { QString labelText = selectedBar->selectionLabel(); - if (labelText.isNull()) { + if (labelText.isNull() || m_selectionLabelDirty) { static const QString rowIndexTag(QStringLiteral("@rowIdx")); static const QString rowLabelTag(QStringLiteral("@rowLabel")); static const QString rowTitleTag(QStringLiteral("@rowTitle")); @@ -1767,6 +1829,7 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) static const QString colTitleTag(QStringLiteral("@colTitle")); static const QString valueTitleTag(QStringLiteral("@valueTitle")); static const QString valueLabelTag(QStringLiteral("@valueLabel")); + static const QString seriesNameTag(QStringLiteral("@seriesName")); // Custom format expects printf format specifier. There is no tag for it. labelText = generateValueLabel( @@ -1797,7 +1860,11 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) labelText.replace(valueLabelTag, valueLabelText); } + labelText.replace(seriesNameTag, + m_visibleSeriesList[m_visualSelectedBarSeriesIndex].name()); + selectedBar->setSelectionLabel(labelText); + m_selectionLabelDirty = false; } m_drawer->generateLabelItem(labelItem, labelText); m_selectedBar = selectedBar; @@ -1825,6 +1892,18 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_selectionDirty = false; } +void Bars3DRenderer::updateMultiSeriesScaling(bool uniform) +{ + m_keepSeriesUniform = uniform; + + // Recalculate scale factors + m_seriesScaleX = 1.0f / float(m_visibleSeriesList.size()); + if (m_keepSeriesUniform) + m_seriesScaleZ = m_seriesScaleX; + else + m_seriesScaleZ = 1.0f; +} + void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative) { // Convert ratio to QSizeF, as we need it in that format for autoscaling calculations @@ -1848,12 +1927,12 @@ void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, const QSizeF &spacin calculateSceneScalingFactors(); } -void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, float min, +void Bars3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max) { Abstract3DRenderer::updateAxisRange(orientation, min, max); - if (orientation == Q3DAbstractAxis::AxisOrientationY) { + if (orientation == QAbstract3DAxis::AxisOrientationY) { calculateHeightAdjustment(); // Check if we have negative values if (min < 0 && !m_hasNegativeValues) { @@ -1903,31 +1982,37 @@ void Bars3DRenderer::updateSelectedBar(const QPoint &position, const QBar3DSerie } } -void Bars3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) +void Bars3DRenderer::resetClickedStatus() +{ + m_clickedPosition = Bars3DController::invalidSelectionPosition(); + m_clickedSeries = 0; +} + +void Bars3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality) { m_cachedShadowQuality = quality; switch (quality) { - case QDataVis::ShadowQualityLow: + case QAbstract3DGraph::ShadowQualityLow: m_shadowQualityToShader = 33.3f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualityMedium: + case QAbstract3DGraph::ShadowQualityMedium: m_shadowQualityToShader = 100.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualityHigh: + case QAbstract3DGraph::ShadowQualityHigh: m_shadowQualityToShader = 200.0f; m_shadowQualityMultiplier = 5; break; - case QDataVis::ShadowQualitySoftLow: + case QAbstract3DGraph::ShadowQualitySoftLow: m_shadowQualityToShader = 7.5f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualitySoftMedium: + case QAbstract3DGraph::ShadowQualitySoftMedium: m_shadowQualityToShader = 10.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualitySoftHigh: + case QAbstract3DGraph::ShadowQualitySoftHigh: m_shadowQualityToShader = 15.0f; m_shadowQualityMultiplier = 4; break; @@ -1982,7 +2067,7 @@ void Bars3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh { if (!m_cachedTheme->isBackgroundEnabled()) { // Load full version of meshes that have it available - // Note: Minimal and Point not supported in bar charts + // Note: Minimal, Point, and Arrow not supported in bar charts if (mesh != QAbstract3DSeries::MeshSphere) fileName.append(QStringLiteral("Full")); } @@ -2035,17 +2120,17 @@ Bars3DController::SelectionType Bars3DRenderer::isSelected(int row, int bar, int { Bars3DController::SelectionType isSelectedType = Bars3DController::SelectionNone; - if ((m_cachedSelectionMode.testFlag(QDataVis::SelectionMultiSeries) + if ((m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionMultiSeries) && m_visualSelectedBarSeriesIndex >= 0) || seriesIndex == m_visualSelectedBarSeriesIndex) { if (row == m_visualSelectedBarPos.x() && bar == m_visualSelectedBarPos.y() - && (m_cachedSelectionMode.testFlag(QDataVis::SelectionItem))) { + && (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem))) { isSelectedType = Bars3DController::SelectionItem; } else if (row == m_visualSelectedBarPos.x() - && (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow))) { + && (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow))) { isSelectedType = Bars3DController::SelectionRow; } else if (bar == m_visualSelectedBarPos.y() - && (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn))) { + && (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn))) { isSelectedType = Bars3DController::SelectionColumn; } } @@ -2150,7 +2235,7 @@ void Bars3DRenderer::updateDepthBuffer() if (m_primarySubViewport.size().isEmpty()) return; - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { m_depthTexture = m_textureHelper->createDepthTextureFrameBuffer(m_primarySubViewport.size(), m_depthFrameBuffer, m_shadowQualityMultiplier); @@ -2177,4 +2262,4 @@ void Bars3DRenderer::initLabelShaders(const QString &vertexShader, const QString m_labelShader->initialize(); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 16e7a476..e53f9bc5 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -26,8 +26,8 @@ // // We mean it. -#ifndef Q3DBARSRENDERER_p_H -#define Q3DBARSRENDERER_p_H +#ifndef Q3DBARSRENDERER_P_H +#define Q3DBARSRENDERER_P_H #include "datavisualizationglobal_p.h" #include "bars3dcontroller_p.h" @@ -39,7 +39,7 @@ class QPoint; class QSizeF; class QOpenGLShaderProgram; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class ShaderHelper; class ObjectHelper; @@ -102,15 +102,19 @@ private: BarRenderItem m_dummyBarRenderItem; QVector<BarRenderItemArray> m_renderingArrays; bool m_noZeroInRange; - float m_seriesScale; + float m_seriesScaleX; + float m_seriesScaleZ; float m_seriesStep; float m_seriesStart; + QPoint m_clickedPosition; + bool m_keepSeriesUniform; public: explicit Bars3DRenderer(Bars3DController *controller); ~Bars3DRenderer(); void updateData(); + void updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); @@ -118,22 +122,23 @@ protected: virtual void initializeOpenGL(); public slots: + void updateMultiSeriesScaling(bool uniform); void updateBarSpecs(GLfloat thicknessRatio = 1.0f, const QSizeF &spacing = QSizeF(1.0, 1.0), bool relative = true); void updateSlicingActive(bool isSlicing); void updateSelectedBar(const QPoint &position, const QBar3DSeries *series); + inline QPoint clickedPosition() const { return m_clickedPosition; } + void resetClickedStatus(); // Overloaded from abstract renderer - virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, float min, float max); - -signals: - void barClicked(QPoint position, QBar3DSeries *series); + virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, + float max); private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void initGradientShaders(const QString &vertexShader, const QString &fragmentShader); - virtual void updateShadowQuality(QDataVis::ShadowQuality quality); + virtual void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality); virtual void updateTextures(); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); @@ -162,7 +167,6 @@ private: friend class BarRenderItem; }; - -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp index f78b2d29..dd82eadc 100644 --- a/src/datavisualization/engine/drawer.cpp +++ b/src/datavisualization/engine/drawer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -16,7 +16,6 @@ ** ****************************************************************************/ -#include "qdatavisualizationenums.h" #include "drawer_p.h" #include "shaderhelper_p.h" #include "objecthelper_p.h" @@ -39,15 +38,13 @@ public: }; StaticLibInitializer staticLibInitializer; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION // Vertex array buffer for point const GLfloat point_data[] = {0.0f, 0.0f, 0.0f}; Drawer::Drawer(Q3DTheme *theme) : m_theme(theme), - m_font(theme->font()), - m_labelBackground(theme->isLabelBackgroundEnabled()), m_textureHelper(0), m_pointbuffer(0) { @@ -71,8 +68,6 @@ void Drawer::initializeOpenGL() void Drawer::setTheme(Q3DTheme *theme) { m_theme = theme; - m_font = m_theme->font(); - m_labelBackground = m_theme->isLabelBackgroundEnabled(); emit drawerChanged(); } @@ -81,25 +76,9 @@ Q3DTheme *Drawer::theme() const return m_theme; } -void Drawer::setFont(const QFont &font) -{ - // We need to be able to override theme's font for drawer - // TODO: (or do we?) - m_font = font; - emit drawerChanged(); -} - QFont Drawer::font() const { - return m_font; -} - -void Drawer::setLabelBackground(bool enabled) -{ - // We need to be able to override theme's label background for drawer - // TODO: (or do we?) - m_labelBackground = enabled; - emit drawerChanged(); + return m_theme->font(); } void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId, @@ -205,7 +184,7 @@ void Drawer::drawPoint(ShaderHelper *shader) void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem, const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, const QVector3D &positionComp, const QVector3D &rotation, - GLfloat itemHeight, QDataVis::SelectionFlags mode, + GLfloat itemHeight, QAbstract3DGraph::SelectionFlags mode, ShaderHelper *shader, ObjectHelper *object, const Q3DCamera *camera, bool useDepth, bool rotateAlong, LabelPosition position, Qt::AlignmentFlag alignment, bool isSlicing) @@ -223,7 +202,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte switch (position) { case LabelBelow: { - yPosition = -2.6f + positionComp.y(); // minus maximum negative height (+ some extra for axis title label) + yPosition = item.translation().y() - (positionComp.y() / 2.0f) + itemHeight - 0.1f; break; } case LabelLow: { @@ -231,79 +210,96 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte break; } case LabelMid: { - // Use this for positioning with absolute item y position value yPosition = item.translation().y(); break; } case LabelHigh: { - // TODO: Fix this. Can't seem to get it right (if ok with positive-only bars, doesn't look good on +- and vice versa) yPosition = item.translation().y() + itemHeight / 2.0f; break; } case LabelOver: { - float mod = 0.3f; - if (itemHeight < 0) - mod = 0.15f; - yPosition = item.translation().y() - (positionComp.y() / 2.0f) + itemHeight + mod; + yPosition = item.translation().y() - (positionComp.y() / 2.0f) + itemHeight + 0.1f; break; } case LabelBottom: { - yPosition = -2.95f + positionComp.y(); + yPosition = -2.75f + positionComp.y(); xPosition = 0.0f; break; } case LabelTop: { - yPosition = 2.95f - positionComp.y(); + yPosition = 2.75f - positionComp.y(); xPosition = 0.0f; break; } case LabelLeft: { yPosition = 0.0f; - xPosition = -2.95f; + xPosition = -2.75f; break; } case LabelRight: { yPosition = 0.0f; - xPosition = 2.95f; + xPosition = 2.75f; break; } } // Calculate scale factor to get uniform font size - GLfloat scaledFontSize = 0.05f + m_font.pointSizeF() / 500.0f; + GLfloat scaledFontSize = 0.05f + m_theme->font().pointSizeF() / 500.0f; GLfloat scaleFactor = scaledFontSize / (GLfloat)textureSize.height(); // Apply alignment GLfloat xAlignment = 0.0f; GLfloat yAlignment = 0.0f; GLfloat zAlignment = 0.0f; + GLfloat sinRotY = qFabs(qSin(qDegreesToRadians(rotation.y()))); + GLfloat cosRotY = qFabs(qCos(qDegreesToRadians(rotation.y()))); + GLfloat sinRotZ = 0.0f; + GLfloat cosRotZ = 0.0f; + if (rotation.z()) { + sinRotZ = qFabs(qSin(qDegreesToRadians(rotation.z()))); + cosRotZ = qFabs(qCos(qDegreesToRadians(rotation.z()))); + } switch (alignment) { case Qt::AlignLeft: { - xAlignment = (-(GLfloat)textureSize.width() * scaleFactor) - * qFabs(qCos(qDegreesToRadians(rotation.y()))); - zAlignment = ((GLfloat)textureSize.width() * scaleFactor) - * qFabs(qSin(qDegreesToRadians(rotation.y()))); + if (rotation.z() && rotation.z() != 180.0f && !rotation.y()) { + xAlignment = ((-(GLfloat)textureSize.width() * scaleFactor) * cosRotZ + - ((GLfloat)textureSize.height() * scaleFactor) * sinRotZ) / 2.0f; + yAlignment = (((GLfloat)textureSize.width() * scaleFactor) * sinRotZ + + ((GLfloat)textureSize.height() * scaleFactor) * cosRotZ) / 2.0f; + } else { + xAlignment = (-(GLfloat)textureSize.width() * scaleFactor) * cosRotY; + zAlignment = ((GLfloat)textureSize.width() * scaleFactor) * sinRotY; + } break; } case Qt::AlignRight: { - xAlignment = ((GLfloat)textureSize.width() * scaleFactor) - * qFabs(qCos(qDegreesToRadians(rotation.y()))); - zAlignment = (-(GLfloat)textureSize.width() * scaleFactor) - * qFabs(qSin(qDegreesToRadians(rotation.y()))); + if (rotation.z() && rotation.z() != 180.0f && !rotation.y()) { + xAlignment = (((GLfloat)textureSize.width() * scaleFactor) * cosRotZ + + ((GLfloat)textureSize.height() * scaleFactor) * sinRotZ) / 2.0f; + yAlignment = (((GLfloat)textureSize.width() * scaleFactor) * sinRotZ + + ((GLfloat)textureSize.height() * scaleFactor) * cosRotZ) / 2.0f; + } else { + xAlignment = ((GLfloat)textureSize.width() * scaleFactor) * cosRotY; + zAlignment = (-(GLfloat)textureSize.width() * scaleFactor) * sinRotY; + } break; } case Qt::AlignTop: { - yAlignment = ((GLfloat)textureSize.width() * scaleFactor) - * qFabs(qCos(qDegreesToRadians(rotation.y()))); - if (itemHeight < 0) - yAlignment = -yAlignment; + yAlignment = ((GLfloat)textureSize.width() * scaleFactor) * cosRotY; break; } case Qt::AlignBottom: { - yAlignment = (-(GLfloat)textureSize.width() * scaleFactor) - * qFabs(qCos(qDegreesToRadians(rotation.y()))); - if (itemHeight < 0) - yAlignment = -yAlignment; + yAlignment = (-(GLfloat)textureSize.width() * scaleFactor) * cosRotY; + break; + } + case Qt::AlignHCenter: { + xAlignment = (-(GLfloat)textureSize.width() * scaleFactor) * cosRotZ + - ((GLfloat)textureSize.height() * scaleFactor) * sinRotZ; + break; + } + case Qt::AlignVCenter: { + yAlignment = ((GLfloat)textureSize.width() * scaleFactor) * cosRotZ + + ((GLfloat)textureSize.height() * scaleFactor) * sinRotZ; break; } default: { @@ -315,7 +311,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte xPosition = item.translation().x(); if (useDepth) zPosition = item.translation().z(); - else if (mode.testFlag(QDataVis::SelectionColumn) && isSlicing) + else if (mode.testFlag(QAbstract3DGraph::SelectionColumn) && isSlicing) xPosition = -(item.translation().z()) + positionComp.z(); // flip first to left } @@ -367,11 +363,11 @@ void Drawer::generateLabelItem(LabelItem &item, const QString &text, int widestL if (!text.isEmpty()) { // Create labels // Print label into a QImage using QPainter - QImage label = Utils::printTextToImage(m_font, + QImage label = Utils::printTextToImage(m_theme->font(), text, m_theme->labelBackgroundColor(), m_theme->labelTextColor(), - m_labelBackground, + m_theme->isLabelBackgroundEnabled(), m_theme->isLabelBorderEnabled(), widestLabel); @@ -382,4 +378,4 @@ void Drawer::generateLabelItem(LabelItem &item, const QString &text, int widestL } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h index 8bc62209..35a0a7ff 100644 --- a/src/datavisualization/engine/drawer_p.h +++ b/src/datavisualization/engine/drawer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -36,7 +36,7 @@ #include "abstractrenderitem_p.h" #include <QFont> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class ShaderHelper; class ObjectHelper; @@ -70,9 +70,7 @@ public: void setTheme(Q3DTheme *theme); Q3DTheme *theme() const; - void setFont(const QFont &font); QFont font() const; - void setLabelBackground(bool enabled); void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0, GLuint depthTextureId = 0); @@ -81,7 +79,7 @@ public: void drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem, const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix, const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight, - QDataVis::SelectionFlags mode, ShaderHelper *shader, ObjectHelper *object, + QAbstract3DGraph::SelectionFlags mode, ShaderHelper *shader, ObjectHelper *object, const Q3DCamera *camera, bool useDepth = false, bool rotateAlong = false, LabelPosition position = LabelOver, Qt::AlignmentFlag alignment = Qt::AlignCenter, bool isSlicing = false); @@ -94,12 +92,10 @@ Q_SIGNALS: private: Q3DTheme *m_theme; - QFont m_font; - bool m_labelBackground; TextureHelper *m_textureHelper; GLuint m_pointbuffer; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/engine.pri b/src/datavisualization/engine/engine.pri index 899979e1..e13a9a04 100644 --- a/src/datavisualization/engine/engine.pri +++ b/src/datavisualization/engine/engine.pri @@ -1,5 +1,5 @@ -HEADERS += $$PWD/q3dwindow_p.h \ - $$PWD/q3dwindow.h \ +HEADERS += $$PWD/qabstract3dgraph_p.h \ + $$PWD/qabstract3dgraph.h \ $$PWD/q3dbars.h \ $$PWD/q3dbars_p.h \ $$PWD/drawer_p.h \ @@ -28,7 +28,7 @@ HEADERS += $$PWD/q3dwindow_p.h \ $$PWD/q3dobject_p.h \ $$PWD/q3dscene_p.h -SOURCES += $$PWD/q3dwindow.cpp \ +SOURCES += $$PWD/qabstract3dgraph.cpp \ $$PWD/q3dbars.cpp \ $$PWD/drawer.cpp \ $$PWD/bars3dcontroller.cpp \ diff --git a/src/datavisualization/engine/engine.qrc b/src/datavisualization/engine/engine.qrc index 8fcaecec..18cba7fe 100644 --- a/src/datavisualization/engine/engine.qrc +++ b/src/datavisualization/engine/engine.qrc @@ -27,6 +27,8 @@ <file alias="negativeBackground">meshes/backgroundNegatives.obj</file> <file alias="minimal">meshes/minimalFlat.obj</file> <file alias="minimalSmooth">meshes/minimalSmooth.obj</file> + <file alias="arrow">meshes/arrowFlat.obj</file> + <file alias="arrowSmooth">meshes/arrowSmooth.obj</file> </qresource> <qresource prefix="/shaders"> <file alias="fragment">shaders/default.frag</file> diff --git a/src/datavisualization/engine/meshes/arrowFlat.obj b/src/datavisualization/engine/meshes/arrowFlat.obj new file mode 100644 index 00000000..bb9762d6 --- /dev/null +++ b/src/datavisualization/engine/meshes/arrowFlat.obj @@ -0,0 +1,403 @@ +# Blender v2.69 (sub 0) OBJ File: 'arrow.blend' +# www.blender.org +v 0.000000 1.000000 0.000000 +v 0.000000 0.000000 -1.000000 +v -0.195090 0.000000 -0.980785 +v -0.382683 0.000000 -0.923880 +v -0.555570 0.000000 -0.831470 +v -0.707107 0.000000 -0.707107 +v -0.831470 0.000000 -0.555570 +v -0.923880 0.000000 -0.382683 +v -0.980785 0.000000 -0.195090 +v -1.000000 0.000000 -0.000000 +v -0.980785 0.000000 0.195090 +v -0.923880 0.000000 0.382683 +v -0.831470 0.000000 0.555570 +v -0.707107 0.000000 0.707107 +v -0.555570 0.000000 0.831470 +v -0.382683 0.000000 0.923880 +v -0.195090 0.000000 0.980785 +v 0.000000 0.000000 1.000000 +v 0.195091 0.000000 0.980785 +v 0.382684 0.000000 0.923879 +v 0.555571 0.000000 0.831469 +v 0.707107 0.000000 0.707106 +v 0.831470 0.000000 0.555570 +v 0.923880 0.000000 0.382683 +v 0.980785 0.000000 0.195089 +v 1.000000 0.000000 -0.000001 +v 0.980785 0.000000 -0.195091 +v 0.923879 0.000000 -0.382684 +v 0.831469 0.000000 -0.555571 +v 0.707106 0.000000 -0.707108 +v 0.555569 0.000000 -0.831470 +v 0.382682 0.000000 -0.923880 +v 0.195089 0.000000 -0.980786 +v 0.000000 0.000000 0.000000 +v 0.000000 0.000000 0.000000 +v -0.000000 0.000000 -0.578860 +v -0.112930 0.000000 -0.567737 +v -0.221520 0.000000 -0.534796 +v -0.321597 0.000000 -0.481304 +v -0.409315 0.000000 -0.409316 +v -0.481304 0.000000 -0.321597 +v -0.534796 0.000000 -0.221520 +v -0.567737 0.000000 -0.112930 +v -0.578859 0.000000 -0.000000 +v -0.567737 0.000000 0.112930 +v -0.534796 0.000000 0.221520 +v -0.481304 0.000000 0.321597 +v -0.409315 0.000000 0.409315 +v -0.321597 0.000000 0.481304 +v -0.221520 0.000000 0.534796 +v -0.112930 0.000000 0.567737 +v 0.000000 0.000000 0.578859 +v 0.112930 0.000000 0.567737 +v 0.221520 0.000000 0.534796 +v 0.321597 0.000000 0.481304 +v 0.409316 0.000000 0.409315 +v 0.481304 0.000000 0.321597 +v 0.534796 0.000000 0.221519 +v 0.567737 0.000000 0.112929 +v 0.578859 0.000000 -0.000001 +v 0.567737 0.000000 -0.112931 +v 0.534796 0.000000 -0.221521 +v 0.481304 0.000000 -0.321598 +v 0.409315 0.000000 -0.409316 +v 0.321596 0.000000 -0.481305 +v 0.221519 0.000000 -0.534797 +v 0.112929 0.000000 -0.567737 +v 0.578859 -1.000000 -0.000001 +v 0.567737 -1.000000 0.112929 +v -0.221520 -1.000000 -0.534796 +v -0.112930 -1.000000 -0.567737 +v -0.321597 -1.000000 0.481304 +v -0.409315 -1.000000 0.409315 +v 0.534796 -1.000000 0.221519 +v 0.481304 -1.000000 0.321597 +v -0.481304 -1.000000 0.321597 +v -0.534796 -1.000000 0.221520 +v 0.112929 -1.000000 -0.567737 +v 0.221519 -1.000000 -0.534797 +v 0.409316 -1.000000 0.409315 +v 0.321597 -1.000000 0.481304 +v -0.567737 -1.000000 0.112930 +v -0.578859 -1.000000 -0.000000 +v 0.321596 -1.000000 -0.481305 +v 0.409315 -1.000000 -0.409316 +v 0.221520 -1.000000 0.534796 +v 0.112930 -1.000000 0.567737 +v -0.567737 -1.000000 -0.112930 +v -0.534796 -1.000000 -0.221520 +v 0.481304 -1.000000 -0.321598 +v 0.534796 -1.000000 -0.221521 +v -0.481304 -1.000000 -0.321597 +v -0.409315 -1.000000 -0.409316 +v 0.000000 -1.000000 0.578859 +v -0.112930 -1.000000 0.567737 +v 0.567737 -1.000000 -0.112931 +v -0.321597 -1.000000 -0.481304 +v -0.221520 -1.000000 0.534796 +v -0.000000 -1.000000 -0.578860 +vt 0.000000 0.000000 +vt 0.549236 0.999900 +vt 0.450764 0.999900 +vt 0.645815 0.980689 +vt 0.354184 0.980689 +vt 0.263208 0.943005 +vt 0.181332 0.888297 +vt 0.111702 0.818667 +vt 0.056994 0.736790 +vt 0.019311 0.645815 +vt 0.000100 0.549235 +vt 0.000100 0.450763 +vt 0.019310 0.354184 +vt 0.056994 0.263208 +vt 0.111702 0.181332 +vt 0.943005 0.263208 +vt 0.818666 0.111702 +vt 0.888296 0.181332 +vt 0.980688 0.354184 +vt 0.999899 0.549236 +vt 0.999899 0.450764 +vt 0.943005 0.736791 +vt 0.980689 0.645815 +vt 0.181332 0.111702 +vt 0.736791 0.943006 +vt 0.263209 0.056994 +vt 0.354185 0.019311 +vt 0.450764 0.000100 +vt 0.818667 0.888298 +vt 0.888297 0.818668 +vt 0.549235 0.000100 +vt 0.645815 0.019311 +vt 0.736791 0.056994 +vn -0.069476 0.705398 -0.705398 +vn -0.205757 0.705398 -0.678290 +vn -0.334131 0.705398 -0.625116 +vn -0.449665 0.705398 -0.547918 +vn -0.547918 0.705398 -0.449665 +vn -0.625116 0.705398 -0.334131 +vn -0.678290 0.705398 -0.205757 +vn -0.705398 0.705398 -0.069476 +vn -0.705398 0.705398 0.069476 +vn -0.678290 0.705398 0.205757 +vn -0.625116 0.705398 0.334131 +vn -0.547918 0.705398 0.449665 +vn -0.449665 0.705398 0.547918 +vn -0.334131 0.705398 0.625116 +vn -0.205757 0.705398 0.678290 +vn -0.069476 0.705398 0.705398 +vn 0.069476 0.705398 0.705398 +vn 0.205757 0.705398 0.678290 +vn 0.334132 0.705398 0.625116 +vn 0.449665 0.705398 0.547918 +vn 0.547919 0.705398 0.449665 +vn 0.625116 0.705398 0.334131 +vn 0.678290 0.705398 0.205756 +vn 0.705398 0.705398 0.069475 +vn 0.705398 0.705398 -0.069476 +vn 0.678290 0.705398 -0.205758 +vn 0.625115 0.705398 -0.334132 +vn 0.547918 0.705398 -0.449666 +vn 0.449664 0.705398 -0.547919 +vn 0.334130 0.705398 -0.625116 +vn 0.205756 0.705398 -0.678290 +vn 0.069475 0.705398 -0.705398 +vn 0.000000 -1.000000 0.000000 +vn -0.290284 0.000000 0.956940 +vn -0.098016 0.000000 0.995185 +vn -0.634393 0.000000 -0.773010 +vn -0.773011 0.000000 -0.634393 +vn 0.956940 0.000000 -0.290286 +vn 0.881921 0.000000 -0.471398 +vn -0.881922 0.000000 -0.471396 +vn -0.956940 0.000000 -0.290285 +vn 0.098017 0.000000 0.995185 +vn 0.290284 0.000000 0.956940 +vn 0.773010 0.000000 -0.634394 +vn 0.634392 0.000000 -0.773011 +vn -0.995185 0.000000 -0.098017 +vn -0.995185 0.000000 0.098017 +vn 0.471397 0.000000 0.881921 +vn 0.634394 0.000000 0.773010 +vn 0.471395 0.000000 -0.881922 +vn 0.290283 0.000000 -0.956941 +vn 0.098017 0.000000 -0.995185 +vn -0.956940 0.000000 0.290285 +vn -0.881921 0.000000 0.471396 +vn 0.773011 0.000000 0.634393 +vn 0.881922 0.000000 0.471396 +vn -0.773010 0.000000 0.634393 +vn -0.634393 0.000000 0.773010 +vn -0.471397 0.000000 0.881921 +vn -0.098018 0.000000 -0.995185 +vn -0.290284 0.000000 -0.956940 +vn -0.471397 0.000000 -0.881921 +vn 0.956941 0.000000 0.290284 +vn 0.995185 0.000000 0.098016 +vn 0.995185 0.000000 -0.098018 +vn 0.000000 -1.000000 -0.000004 +vn 0.000000 -1.000000 -0.000001 +vn 0.000000 -1.000000 0.000001 +vn -0.098017 0.000000 0.995185 +vn -0.773010 0.000000 -0.634393 +vn -0.881921 0.000000 -0.471396 +vn 0.098018 0.000000 0.995185 +vn 0.290285 0.000000 0.956940 +vn 0.773009 0.000000 -0.634394 +vn 0.471396 0.000000 -0.881922 +vn -0.881921 0.000000 0.471397 +vn -0.098017 0.000000 -0.995185 +vn -0.471396 0.000000 -0.881921 +s off +f 1/1/1 2/1/1 3/1/1 +f 1/1/2 3/1/2 4/1/2 +f 1/1/3 4/1/3 5/1/3 +f 1/1/4 5/1/4 6/1/4 +f 1/1/5 6/1/5 7/1/5 +f 1/1/6 7/1/6 8/1/6 +f 1/1/7 8/1/7 9/1/7 +f 1/1/8 9/1/8 10/1/8 +f 1/1/9 10/1/9 11/1/9 +f 1/1/10 11/1/10 12/1/10 +f 1/1/11 12/1/11 13/1/11 +f 1/1/12 13/1/12 14/1/12 +f 1/1/13 14/1/13 15/1/13 +f 1/1/14 15/1/14 16/1/14 +f 1/1/15 16/1/15 17/1/15 +f 1/1/16 17/1/16 18/1/16 +f 1/1/17 18/1/17 19/1/17 +f 1/1/18 19/1/18 20/1/18 +f 1/1/19 20/1/19 21/1/19 +f 1/1/20 21/1/20 22/1/20 +f 1/1/21 22/1/21 23/1/21 +f 1/1/22 23/1/22 24/1/22 +f 1/1/23 24/1/23 25/1/23 +f 1/1/24 25/1/24 26/1/24 +f 1/1/25 26/1/25 27/1/25 +f 1/1/26 27/1/26 28/1/26 +f 1/1/27 28/1/27 29/1/27 +f 1/1/28 29/1/28 30/1/28 +f 1/1/29 30/1/29 31/1/29 +f 1/1/30 31/1/30 32/1/30 +f 1/1/31 32/1/31 33/1/31 +f 1/1/32 33/1/32 2/1/32 +f 24/1/33 23/1/33 58/1/33 +f 13/1/33 12/1/33 47/1/33 +f 2/1/33 33/1/33 36/1/33 +f 23/1/33 22/1/33 57/1/33 +f 12/1/33 11/1/33 46/1/33 +f 33/1/33 32/1/33 67/1/33 +f 22/1/33 21/1/33 56/1/33 +f 11/1/33 10/1/33 45/1/33 +f 32/1/33 31/1/33 66/1/33 +f 21/1/33 20/1/33 55/1/33 +f 10/1/33 9/1/33 44/1/33 +f 31/1/33 30/1/33 65/1/33 +f 20/1/33 19/1/33 54/1/33 +f 9/1/33 8/1/33 43/1/33 +f 30/1/33 29/1/33 64/1/33 +f 19/1/33 18/1/33 53/1/33 +f 3/1/33 2/1/33 37/1/33 +f 8/1/33 7/1/33 42/1/33 +f 29/1/33 28/1/33 63/1/33 +f 7/1/33 6/1/33 41/1/33 +f 18/1/33 17/1/33 52/1/33 +f 28/1/33 27/1/33 62/1/33 +f 6/1/33 5/1/33 40/1/33 +f 17/1/33 16/1/33 51/1/33 +f 27/1/33 26/1/33 61/1/33 +f 5/1/33 4/1/33 39/1/33 +f 16/1/33 15/1/33 50/1/33 +f 26/1/33 25/1/33 60/1/33 +f 4/1/33 3/1/33 38/1/33 +f 15/1/33 14/1/33 49/1/33 +f 25/1/33 24/1/33 59/1/33 +f 14/1/33 13/1/33 48/1/33 +f 81/2/33 86/3/33 80/4/33 +f 51/1/34 50/1/34 95/1/34 +f 52/1/35 51/1/35 94/1/35 +f 40/1/36 39/1/36 93/1/36 +f 41/1/37 40/1/37 92/1/37 +f 62/1/38 61/1/38 91/1/38 +f 63/1/39 62/1/39 90/1/39 +f 42/1/40 41/1/40 89/1/40 +f 43/1/41 42/1/41 88/1/41 +f 53/1/42 52/1/42 87/1/42 +f 54/1/43 53/1/43 86/1/43 +f 64/1/44 63/1/44 85/1/44 +f 65/1/45 64/1/45 84/1/45 +f 44/1/46 43/1/46 83/1/46 +f 45/1/47 44/1/47 82/1/47 +f 55/1/48 54/1/48 81/1/48 +f 56/1/49 55/1/49 80/1/49 +f 66/1/50 65/1/50 79/1/50 +f 67/1/51 66/1/51 78/1/51 +f 36/1/52 67/1/52 99/1/52 +f 46/1/53 45/1/53 77/1/53 +f 47/1/54 46/1/54 76/1/54 +f 57/1/55 56/1/55 75/1/55 +f 58/1/56 57/1/56 74/1/56 +f 48/1/57 47/1/57 73/1/57 +f 49/1/58 48/1/58 72/1/58 +f 50/1/59 49/1/59 98/1/59 +f 37/1/60 36/1/60 71/1/60 +f 38/1/61 37/1/61 70/1/61 +f 39/1/62 38/1/62 97/1/62 +f 59/1/63 58/1/63 69/1/63 +f 60/1/64 59/1/64 68/1/64 +f 61/1/65 60/1/65 96/1/65 +f 23/1/33 57/1/33 58/1/33 +f 12/1/33 46/1/33 47/1/33 +f 33/1/33 67/1/33 36/1/33 +f 22/1/33 56/1/33 57/1/33 +f 11/1/33 45/1/33 46/1/33 +f 32/1/33 66/1/33 67/1/33 +f 21/1/33 55/1/33 56/1/33 +f 10/1/33 44/1/33 45/1/33 +f 31/1/33 65/1/33 66/1/33 +f 20/1/33 54/1/33 55/1/33 +f 9/1/33 43/1/33 44/1/33 +f 30/1/33 64/1/33 65/1/33 +f 19/1/33 53/1/33 54/1/33 +f 8/1/33 42/1/33 43/1/33 +f 29/1/33 63/1/33 64/1/33 +f 18/1/33 52/1/33 53/1/33 +f 2/1/33 36/1/33 37/1/33 +f 7/1/33 41/1/33 42/1/33 +f 28/1/33 62/1/33 63/1/33 +f 6/1/33 40/1/33 41/1/33 +f 17/1/33 51/1/33 52/1/33 +f 27/1/33 61/1/33 62/1/33 +f 5/1/33 39/1/33 40/1/33 +f 16/1/33 50/1/33 51/1/33 +f 26/1/33 60/1/33 61/1/33 +f 4/1/33 38/1/33 39/1/33 +f 15/1/33 49/1/33 50/1/33 +f 25/1/33 59/1/33 60/1/33 +f 3/1/33 37/1/33 38/1/33 +f 14/1/33 48/1/33 49/1/33 +f 24/1/33 58/1/33 59/1/33 +f 13/1/33 47/1/33 48/1/33 +f 86/3/33 87/5/33 80/4/33 +f 87/5/66 94/6/66 80/4/66 +f 94/6/33 95/7/33 80/4/33 +f 95/7/33 98/8/33 80/4/33 +f 98/8/33 72/9/33 80/4/33 +f 72/9/33 73/10/33 80/4/33 +f 73/10/33 76/11/33 80/4/33 +f 76/11/33 77/12/33 80/4/33 +f 77/12/67 82/13/67 80/4/67 +f 82/13/33 83/14/33 80/4/33 +f 83/14/68 88/15/68 80/4/68 +f 84/16/33 78/17/33 79/18/33 +f 85/19/66 78/17/66 84/16/66 +f 91/20/33 85/19/33 90/21/33 +f 91/20/33 78/17/33 85/19/33 +f 68/22/33 91/20/33 96/23/33 +f 68/22/33 78/17/33 91/20/33 +f 88/15/67 89/24/67 80/4/67 +f 80/4/33 89/24/33 75/25/33 +f 89/24/33 92/26/33 75/25/33 +f 92/26/68 93/27/68 75/25/68 +f 93/27/33 97/28/33 75/25/33 +f 75/25/33 97/28/33 74/29/33 +f 69/30/33 78/17/33 68/22/33 +f 74/29/33 97/28/33 69/30/33 +f 97/28/33 70/31/33 69/30/33 +f 70/31/68 71/32/68 69/30/68 +f 71/32/33 99/33/33 69/30/33 +f 99/33/33 78/17/33 69/30/33 +f 50/1/34 98/1/34 95/1/34 +f 51/1/69 95/1/69 94/1/69 +f 39/1/36 97/1/36 93/1/36 +f 40/1/70 93/1/70 92/1/70 +f 61/1/38 96/1/38 91/1/38 +f 62/1/39 91/1/39 90/1/39 +f 41/1/71 92/1/71 89/1/71 +f 42/1/41 89/1/41 88/1/41 +f 52/1/72 94/1/72 87/1/72 +f 53/1/73 87/1/73 86/1/73 +f 63/1/74 90/1/74 85/1/74 +f 64/1/45 85/1/45 84/1/45 +f 43/1/46 88/1/46 83/1/46 +f 44/1/47 83/1/47 82/1/47 +f 54/1/48 86/1/48 81/1/48 +f 55/1/49 81/1/49 80/1/49 +f 65/1/75 84/1/75 79/1/75 +f 66/1/51 79/1/51 78/1/51 +f 67/1/52 78/1/52 99/1/52 +f 45/1/53 82/1/53 77/1/53 +f 46/1/76 77/1/76 76/1/76 +f 56/1/55 80/1/55 75/1/55 +f 57/1/56 75/1/56 74/1/56 +f 47/1/57 76/1/57 73/1/57 +f 48/1/58 73/1/58 72/1/58 +f 49/1/59 72/1/59 98/1/59 +f 36/1/77 99/1/77 71/1/77 +f 37/1/61 71/1/61 70/1/61 +f 38/1/78 70/1/78 97/1/78 +f 58/1/63 74/1/63 69/1/63 +f 59/1/64 69/1/64 68/1/64 +f 60/1/65 68/1/65 96/1/65 diff --git a/src/datavisualization/engine/meshes/arrowSmooth.obj b/src/datavisualization/engine/meshes/arrowSmooth.obj new file mode 100644 index 00000000..898c4a2b --- /dev/null +++ b/src/datavisualization/engine/meshes/arrowSmooth.obj @@ -0,0 +1,422 @@ +# Blender v2.69 (sub 0) OBJ File: 'arrow.blend' +# www.blender.org +v 0.000000 1.000000 0.000000 +v 0.000000 0.000000 -1.000000 +v -0.195090 0.000000 -0.980785 +v -0.382683 0.000000 -0.923880 +v -0.555570 0.000000 -0.831470 +v -0.707107 0.000000 -0.707107 +v -0.831470 0.000000 -0.555570 +v -0.923880 0.000000 -0.382683 +v -0.980785 0.000000 -0.195090 +v -1.000000 0.000000 -0.000000 +v -0.980785 0.000000 0.195090 +v -0.923880 0.000000 0.382683 +v -0.831470 0.000000 0.555570 +v -0.707107 0.000000 0.707107 +v -0.555570 0.000000 0.831470 +v -0.382683 0.000000 0.923880 +v -0.195090 0.000000 0.980785 +v 0.000000 0.000000 1.000000 +v 0.195091 0.000000 0.980785 +v 0.382684 0.000000 0.923879 +v 0.555571 0.000000 0.831469 +v 0.707107 0.000000 0.707106 +v 0.831470 0.000000 0.555570 +v 0.923880 0.000000 0.382683 +v 0.980785 0.000000 0.195089 +v 1.000000 0.000000 -0.000001 +v 0.980785 0.000000 -0.195091 +v 0.923879 0.000000 -0.382684 +v 0.831469 0.000000 -0.555571 +v 0.707106 0.000000 -0.707108 +v 0.555569 0.000000 -0.831470 +v 0.382682 0.000000 -0.923880 +v 0.195089 0.000000 -0.980786 +v 0.000000 0.000000 0.000000 +v 0.000000 0.000000 0.000000 +v -0.000000 0.000000 -0.578860 +v -0.112930 0.000000 -0.567737 +v -0.221520 0.000000 -0.534796 +v -0.321597 0.000000 -0.481304 +v -0.409315 0.000000 -0.409316 +v -0.481304 0.000000 -0.321597 +v -0.534796 0.000000 -0.221520 +v -0.567737 0.000000 -0.112930 +v -0.578859 0.000000 -0.000000 +v -0.567737 0.000000 0.112930 +v -0.534796 0.000000 0.221520 +v -0.481304 0.000000 0.321597 +v -0.409315 0.000000 0.409315 +v -0.321597 0.000000 0.481304 +v -0.221520 0.000000 0.534796 +v -0.112930 0.000000 0.567737 +v 0.000000 0.000000 0.578859 +v 0.112930 0.000000 0.567737 +v 0.221520 0.000000 0.534796 +v 0.321597 0.000000 0.481304 +v 0.409316 0.000000 0.409315 +v 0.481304 0.000000 0.321597 +v 0.534796 0.000000 0.221519 +v 0.567737 0.000000 0.112929 +v 0.578859 0.000000 -0.000001 +v 0.567737 0.000000 -0.112931 +v 0.534796 0.000000 -0.221521 +v 0.481304 0.000000 -0.321598 +v 0.409315 0.000000 -0.409316 +v 0.321596 0.000000 -0.481305 +v 0.221519 0.000000 -0.534797 +v 0.112929 0.000000 -0.567737 +v 0.578859 -1.000000 -0.000001 +v 0.567737 -1.000000 0.112929 +v -0.221520 -1.000000 -0.534796 +v -0.112930 -1.000000 -0.567737 +v -0.321597 -1.000000 0.481304 +v -0.409315 -1.000000 0.409315 +v 0.534796 -1.000000 0.221519 +v 0.481304 -1.000000 0.321597 +v -0.481304 -1.000000 0.321597 +v -0.534796 -1.000000 0.221520 +v 0.112929 -1.000000 -0.567737 +v 0.221519 -1.000000 -0.534797 +v 0.409316 -1.000000 0.409315 +v 0.321597 -1.000000 0.481304 +v -0.567737 -1.000000 0.112930 +v -0.578859 -1.000000 -0.000000 +v 0.321596 -1.000000 -0.481305 +v 0.409315 -1.000000 -0.409316 +v 0.221520 -1.000000 0.534796 +v 0.112930 -1.000000 0.567737 +v -0.567737 -1.000000 -0.112930 +v -0.534796 -1.000000 -0.221520 +v 0.481304 -1.000000 -0.321598 +v 0.534796 -1.000000 -0.221521 +v -0.481304 -1.000000 -0.321597 +v -0.409315 -1.000000 -0.409316 +v 0.000000 -1.000000 0.578859 +v -0.112930 -1.000000 0.567737 +v 0.567737 -1.000000 -0.112931 +v -0.321597 -1.000000 -0.481304 +v -0.221520 -1.000000 0.534796 +v -0.000000 -1.000000 -0.578860 +vt 0.000000 0.000000 +vt 0.549236 0.999900 +vt 0.450764 0.999900 +vt 0.645815 0.980689 +vt 0.354184 0.980689 +vt 0.263208 0.943005 +vt 0.181332 0.888297 +vt 0.111702 0.818667 +vt 0.056994 0.736790 +vt 0.019311 0.645815 +vt 0.000100 0.549235 +vt 0.000100 0.450763 +vt 0.019310 0.354184 +vt 0.056994 0.263208 +vt 0.111702 0.181332 +vt 0.943005 0.263208 +vt 0.818666 0.111702 +vt 0.888296 0.181332 +vt 0.980688 0.354184 +vt 0.999899 0.549236 +vt 0.999899 0.450764 +vt 0.943005 0.736791 +vt 0.980689 0.645815 +vt 0.181332 0.111702 +vt 0.736791 0.943006 +vt 0.263209 0.056994 +vt 0.354185 0.019311 +vt 0.450764 0.000100 +vt 0.818667 0.888298 +vt 0.888297 0.818668 +vt 0.549235 0.000100 +vt 0.645815 0.019311 +vt 0.736791 0.056994 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.363689 -0.931516 +vn -0.181707 -0.363689 -0.913602 +vn -0.356456 -0.363689 -0.860591 +vn -0.517502 -0.363689 -0.774499 +vn -0.658681 -0.363689 -0.658681 +vn -0.774499 -0.363689 -0.517502 +vn -0.860591 -0.363689 -0.356456 +vn -0.913602 -0.363689 -0.181707 +vn -0.931516 -0.363689 0.000000 +vn -0.913602 -0.363689 0.181707 +vn -0.860591 -0.363689 0.356456 +vn -0.774499 -0.363689 0.517502 +vn -0.658681 -0.363689 0.658681 +vn -0.517502 -0.363689 0.774499 +vn -0.356456 -0.363689 0.860591 +vn -0.181707 -0.363689 0.913602 +vn 0.000000 -0.363689 0.931516 +vn 0.181707 -0.363689 0.913602 +vn 0.356456 -0.363689 0.860591 +vn 0.517502 -0.363689 0.774499 +vn 0.658681 -0.363689 0.658681 +vn 0.774499 -0.363689 0.517502 +vn 0.860591 -0.363689 0.356456 +vn 0.913602 -0.363689 0.181707 +vn 0.931516 -0.363689 0.000000 +vn 0.913602 -0.363689 -0.181707 +vn 0.860591 -0.363689 -0.356456 +vn 0.774499 -0.363689 -0.517502 +vn 0.658681 -0.363689 -0.658681 +vn 0.517502 -0.363689 -0.774499 +vn 0.356456 -0.363689 -0.860591 +vn 0.181707 -0.363689 -0.913602 +vn 0.631550 -0.729820 0.261605 +vn -0.568377 -0.729820 0.379772 +vn 0.000000 -0.729820 -0.683584 +vn 0.568377 -0.729820 0.379772 +vn -0.631550 -0.729820 0.261605 +vn 0.133335 -0.729820 -0.670461 +vn 0.483383 -0.729820 0.483383 +vn -0.670461 -0.729820 0.133335 +vn 0.261574 -0.729820 -0.631550 +vn 0.379772 -0.729820 0.568377 +vn -0.683584 -0.729820 0.000000 +vn 0.379772 -0.729820 -0.568377 +vn 0.261605 -0.729820 0.631550 +vn -0.670461 -0.729820 -0.133335 +vn 0.483383 -0.729820 -0.483383 +vn 0.133335 -0.729820 0.670461 +vn -0.133335 -0.729820 -0.670461 +vn -0.631550 -0.729820 -0.261605 +vn 0.568377 -0.729820 -0.379772 +vn -0.568377 -0.729820 -0.379772 +vn 0.000000 -0.729820 0.683584 +vn 0.631550 -0.729820 -0.261605 +vn -0.483383 -0.729820 -0.483383 +vn -0.133335 -0.729820 0.670461 +vn 0.670461 -0.729820 -0.133366 +vn -0.379772 -0.729820 -0.568377 +vn -0.261605 -0.729820 0.631550 +vn 0.683584 -0.729820 0.000000 +vn -0.261605 -0.729820 -0.631550 +vn -0.379772 -0.729820 0.568377 +vn 0.670461 -0.729820 0.133335 +vn -0.483383 -0.729820 0.483383 +vn 0.404370 -0.685690 0.605213 +vn 0.278542 -0.685690 0.672475 +vn 0.514695 -0.685690 0.514664 +vn -0.142003 -0.685690 0.713889 +vn 0.000000 -0.685690 0.727866 +vn -0.514664 -0.685690 -0.514664 +vn -0.605213 -0.685690 -0.404370 +vn 0.672475 -0.685690 -0.278542 +vn 0.605213 -0.685690 -0.404370 +vn -0.672475 -0.685690 -0.278542 +vn -0.713889 -0.685690 -0.142003 +vn 0.142003 -0.685690 0.713889 +vn 0.514664 -0.685690 -0.514695 +vn 0.404370 -0.685690 -0.605213 +vn -0.727866 -0.685690 0.000000 +vn -0.713889 -0.685690 0.142003 +vn 0.278542 -0.685690 -0.672475 +vn 0.142003 -0.685690 -0.713889 +vn 0.000000 -0.685690 -0.727866 +vn -0.672475 -0.685690 0.278542 +vn -0.605213 -0.685690 0.404370 +vn 0.605213 -0.685690 0.404370 +vn 0.672475 -0.685690 0.278542 +vn -0.514664 -0.685690 0.514664 +vn -0.404370 -0.685690 0.605213 +vn -0.278542 -0.685690 0.672475 +vn -0.142003 -0.685690 -0.713889 +vn -0.278542 -0.685690 -0.672475 +vn -0.404370 -0.685690 -0.605213 +vn 0.713889 -0.685690 0.142003 +vn 0.727866 -0.685690 0.000000 +vn 0.713889 -0.685690 -0.142003 +s 1 +f 1/1/1 2/1/2 3/1/3 +f 1/1/1 3/1/3 4/1/4 +f 1/1/1 4/1/4 5/1/5 +f 1/1/1 5/1/5 6/1/6 +f 1/1/1 6/1/6 7/1/7 +f 1/1/1 7/1/7 8/1/8 +f 1/1/1 8/1/8 9/1/9 +f 1/1/1 9/1/9 10/1/10 +f 1/1/1 10/1/10 11/1/11 +f 1/1/1 11/1/11 12/1/12 +f 1/1/1 12/1/12 13/1/13 +f 1/1/1 13/1/13 14/1/14 +f 1/1/1 14/1/14 15/1/15 +f 1/1/1 15/1/15 16/1/16 +f 1/1/1 16/1/16 17/1/17 +f 1/1/1 17/1/17 18/1/18 +f 1/1/1 18/1/18 19/1/19 +f 1/1/1 19/1/19 20/1/20 +f 1/1/1 20/1/20 21/1/21 +f 1/1/1 21/1/21 22/1/22 +f 1/1/1 22/1/22 23/1/23 +f 1/1/1 23/1/23 24/1/24 +f 1/1/1 24/1/24 25/1/25 +f 1/1/1 25/1/25 26/1/26 +f 1/1/1 26/1/26 27/1/27 +f 1/1/1 27/1/27 28/1/28 +f 1/1/1 28/1/28 29/1/29 +f 1/1/1 29/1/29 30/1/30 +f 1/1/1 30/1/30 31/1/31 +f 1/1/1 31/1/31 32/1/32 +f 1/1/1 32/1/32 33/1/33 +f 1/1/1 33/1/33 2/1/2 +f 24/1/24 23/1/23 58/1/34 +f 13/1/13 12/1/12 47/1/35 +f 2/1/2 33/1/33 36/1/36 +f 23/1/23 22/1/22 57/1/37 +f 12/1/12 11/1/11 46/1/38 +f 33/1/33 32/1/32 67/1/39 +f 22/1/22 21/1/21 56/1/40 +f 11/1/11 10/1/10 45/1/41 +f 32/1/32 31/1/31 66/1/42 +f 21/1/21 20/1/20 55/1/43 +f 10/1/10 9/1/9 44/1/44 +f 31/1/31 30/1/30 65/1/45 +f 20/1/20 19/1/19 54/1/46 +f 9/1/9 8/1/8 43/1/47 +f 30/1/30 29/1/29 64/1/48 +f 19/1/19 18/1/18 53/1/49 +f 3/1/3 2/1/2 37/1/50 +f 8/1/8 7/1/7 42/1/51 +f 29/1/29 28/1/28 63/1/52 +f 7/1/7 6/1/6 41/1/53 +f 18/1/18 17/1/17 52/1/54 +f 28/1/28 27/1/27 62/1/55 +f 6/1/6 5/1/5 40/1/56 +f 17/1/17 16/1/16 51/1/57 +f 27/1/27 26/1/26 61/1/58 +f 5/1/5 4/1/4 39/1/59 +f 16/1/16 15/1/15 50/1/60 +f 26/1/26 25/1/25 60/1/61 +f 4/1/4 3/1/3 38/1/62 +f 15/1/15 14/1/14 49/1/63 +f 25/1/25 24/1/24 59/1/64 +f 14/1/14 13/1/13 48/1/65 +f 81/2/66 86/3/67 80/4/68 +f 51/1/57 50/1/60 95/1/69 +f 52/1/54 51/1/57 94/1/70 +f 40/1/56 39/1/59 93/1/71 +f 41/1/53 40/1/56 92/1/72 +f 62/1/55 61/1/58 91/1/73 +f 63/1/52 62/1/55 90/1/74 +f 42/1/51 41/1/53 89/1/75 +f 43/1/47 42/1/51 88/1/76 +f 53/1/49 52/1/54 87/1/77 +f 54/1/46 53/1/49 86/1/67 +f 64/1/48 63/1/52 85/1/78 +f 65/1/45 64/1/48 84/1/79 +f 44/1/44 43/1/47 83/1/80 +f 45/1/41 44/1/44 82/1/81 +f 55/1/43 54/1/46 81/1/66 +f 56/1/40 55/1/43 80/1/68 +f 66/1/42 65/1/45 79/1/82 +f 67/1/39 66/1/42 78/1/83 +f 36/1/36 67/1/39 99/1/84 +f 46/1/38 45/1/41 77/1/85 +f 47/1/35 46/1/38 76/1/86 +f 57/1/37 56/1/40 75/1/87 +f 58/1/34 57/1/37 74/1/88 +f 48/1/65 47/1/35 73/1/89 +f 49/1/63 48/1/65 72/1/90 +f 50/1/60 49/1/63 98/1/91 +f 37/1/50 36/1/36 71/1/92 +f 38/1/62 37/1/50 70/1/93 +f 39/1/59 38/1/62 97/1/94 +f 59/1/64 58/1/34 69/1/95 +f 60/1/61 59/1/64 68/1/96 +f 61/1/58 60/1/61 96/1/97 +f 23/1/23 57/1/37 58/1/34 +f 12/1/12 46/1/38 47/1/35 +f 33/1/33 67/1/39 36/1/36 +f 22/1/22 56/1/40 57/1/37 +f 11/1/11 45/1/41 46/1/38 +f 32/1/32 66/1/42 67/1/39 +f 21/1/21 55/1/43 56/1/40 +f 10/1/10 44/1/44 45/1/41 +f 31/1/31 65/1/45 66/1/42 +f 20/1/20 54/1/46 55/1/43 +f 9/1/9 43/1/47 44/1/44 +f 30/1/30 64/1/48 65/1/45 +f 19/1/19 53/1/49 54/1/46 +f 8/1/8 42/1/51 43/1/47 +f 29/1/29 63/1/52 64/1/48 +f 18/1/18 52/1/54 53/1/49 +f 2/1/2 36/1/36 37/1/50 +f 7/1/7 41/1/53 42/1/51 +f 28/1/28 62/1/55 63/1/52 +f 6/1/6 40/1/56 41/1/53 +f 17/1/17 51/1/57 52/1/54 +f 27/1/27 61/1/58 62/1/55 +f 5/1/5 39/1/59 40/1/56 +f 16/1/16 50/1/60 51/1/57 +f 26/1/26 60/1/61 61/1/58 +f 4/1/4 38/1/62 39/1/59 +f 15/1/15 49/1/63 50/1/60 +f 25/1/25 59/1/64 60/1/61 +f 3/1/3 37/1/50 38/1/62 +f 14/1/14 48/1/65 49/1/63 +f 24/1/24 58/1/34 59/1/64 +f 13/1/13 47/1/35 48/1/65 +f 86/3/67 87/5/77 80/4/68 +f 87/5/77 94/6/70 80/4/68 +f 94/6/70 95/7/69 80/4/68 +f 95/7/69 98/8/91 80/4/68 +f 98/8/91 72/9/90 80/4/68 +f 72/9/90 73/10/89 80/4/68 +f 73/10/89 76/11/86 80/4/68 +f 76/11/86 77/12/85 80/4/68 +f 77/12/85 82/13/81 80/4/68 +f 82/13/81 83/14/80 80/4/68 +f 83/14/80 88/15/76 80/4/68 +f 84/16/79 78/17/83 79/18/82 +f 85/19/78 78/17/83 84/16/79 +f 91/20/73 85/19/78 90/21/74 +f 91/20/73 78/17/83 85/19/78 +f 68/22/96 91/20/73 96/23/97 +f 68/22/96 78/17/83 91/20/73 +f 88/15/76 89/24/75 80/4/68 +f 80/4/68 89/24/75 75/25/87 +f 89/24/75 92/26/72 75/25/87 +f 92/26/72 93/27/71 75/25/87 +f 93/27/71 97/28/94 75/25/87 +f 75/25/87 97/28/94 74/29/88 +f 69/30/95 78/17/83 68/22/96 +f 74/29/88 97/28/94 69/30/95 +f 97/28/94 70/31/93 69/30/95 +f 70/31/93 71/32/92 69/30/95 +f 71/32/92 99/33/84 69/30/95 +f 99/33/84 78/17/83 69/30/95 +f 50/1/60 98/1/91 95/1/69 +f 51/1/57 95/1/69 94/1/70 +f 39/1/59 97/1/94 93/1/71 +f 40/1/56 93/1/71 92/1/72 +f 61/1/58 96/1/97 91/1/73 +f 62/1/55 91/1/73 90/1/74 +f 41/1/53 92/1/72 89/1/75 +f 42/1/51 89/1/75 88/1/76 +f 52/1/54 94/1/70 87/1/77 +f 53/1/49 87/1/77 86/1/67 +f 63/1/52 90/1/74 85/1/78 +f 64/1/48 85/1/78 84/1/79 +f 43/1/47 88/1/76 83/1/80 +f 44/1/44 83/1/80 82/1/81 +f 54/1/46 86/1/67 81/1/66 +f 55/1/43 81/1/66 80/1/68 +f 65/1/45 84/1/79 79/1/82 +f 66/1/42 79/1/82 78/1/83 +f 67/1/39 78/1/83 99/1/84 +f 45/1/41 82/1/81 77/1/85 +f 46/1/38 77/1/85 76/1/86 +f 56/1/40 80/1/68 75/1/87 +f 57/1/37 75/1/87 74/1/88 +f 47/1/35 76/1/86 73/1/89 +f 48/1/65 73/1/89 72/1/90 +f 49/1/63 72/1/90 98/1/91 +f 36/1/36 99/1/84 71/1/92 +f 37/1/50 71/1/92 70/1/93 +f 38/1/62 70/1/93 97/1/94 +f 58/1/34 74/1/88 69/1/95 +f 59/1/64 69/1/95 68/1/96 +f 60/1/61 68/1/96 96/1/97 diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index d4e97519..787033ad 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,15 +19,12 @@ #include "q3dbars.h" #include "q3dbars_p.h" #include "bars3dcontroller_p.h" -#include "q3dvalueaxis.h" -#include "q3dcategoryaxis.h" +#include "qvalue3daxis.h" +#include "qcategory3daxis.h" #include "q3dcamera.h" #include "qbar3dseries_p.h" -#include <QMouseEvent> - - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DBars @@ -96,24 +93,17 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! - * Constructs a new 3D bar graph with optional \a parent window. + * Constructs a new 3D bar graph with optional \a parent window + * and surface \a format. */ -Q3DBars::Q3DBars(QWindow *parent) - : Q3DWindow(new Q3DBarsPrivate(this), parent) +Q3DBars::Q3DBars(const QSurfaceFormat *format, QWindow *parent) + : QAbstract3DGraph(new Q3DBarsPrivate(this), format, parent) { dptr()->m_shared = new Bars3DController(geometry()); d_ptr->setVisualController(dptr()->m_shared); dptr()->m_shared->initializeOpenGL(); - QObject::connect(dptr()->m_shared, &Abstract3DController::selectionModeChanged, this, - &Q3DBars::selectionModeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, - &Q3DBars::shadowQualityChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DBars::themeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), - &Q3DWindowPrivate::renderLater); - QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, dptr(), - &Q3DBarsPrivate::handleShadowQualityUpdate); + QObject::connect(dptr()->m_shared, &Bars3DController::primarySeriesChanged, + this, &Q3DBars::primarySeriesChanged); } /*! @@ -124,12 +114,37 @@ Q3DBars::~Q3DBars() } /*! + * \property Q3DBars::primarySeries + * + * Specifies the \a series that is the primary series of the graph. The primary series + * is used to determine the row and column axis labels when the labels are not explicitly + * set to the axes. + * If the specified \a series is not already added to the graph, setting it as the + * primary series will also implicitly add it to the graph. + * If the primary series itself is removed from the graph, this property + * resets to default. + * If \a series is null, this property resets to default. + * Defaults to the first added series or zero if no series are added to the graph. + */ +void Q3DBars::setPrimarySeries(QBar3DSeries *series) +{ + dptr()->m_shared->setPrimarySeries(series); +} + +QBar3DSeries *Q3DBars::primarySeries() const +{ + return dptrc()->m_shared->primarySeries(); +} + +/*! * Adds the \a series to the graph. A graph can contain multiple series, but only one set of axes, * so the rows and columns of all series must match for the visualized data to be meaningful. * If the graph has multiple visible series, only the first one added will * generate the row or column labels on the axes in cases where the labels are not explicitly set * to the axes. If the newly added series has specified a selected bar, it will be highlighted and * any existing selection will be cleared. Only one added series can have an active selection. + * + * /sa seriesList() */ void Q3DBars::addSeries(QBar3DSeries *series) { @@ -145,70 +160,46 @@ void Q3DBars::removeSeries(QBar3DSeries *series) } /*! - * \return list of series added to this graph. - */ -QList<QBar3DSeries *> Q3DBars::seriesList() -{ - return dptr()->m_shared->barSeriesList(); -} - -/*! - * \internal - */ -void Q3DBars::mouseDoubleClickEvent(QMouseEvent *event) -{ - dptr()->m_shared->mouseDoubleClickEvent(event); -} - -/*! - * \internal - */ -void Q3DBars::touchEvent(QTouchEvent *event) -{ - dptr()->m_shared->touchEvent(event); -} - -/*! - * \internal - */ -void Q3DBars::mousePressEvent(QMouseEvent *event) -{ - dptr()->m_shared->mousePressEvent(event, event->pos()); -} - -/*! - * \internal + * Inserts the \a series into the position \a index in the series list. + * If the \a series has already been added to the list, it is moved to the + * new \a index. + * \note When moving a series to a new \a index that is after its old index, + * the new position in list is calculated as if the series was still in its old + * index, so the final index is actually the \a index decremented by one. + * + * \sa addSeries(), seriesList() */ -void Q3DBars::mouseReleaseEvent(QMouseEvent *event) +void Q3DBars::insertSeries(int index, QBar3DSeries *series) { - dptr()->m_shared->mouseReleaseEvent(event, event->pos()); + dptr()->m_shared->insertSeries(index, series); } /*! - * \internal + * \return list of series added to this graph. */ -void Q3DBars::mouseMoveEvent(QMouseEvent *event) +QList<QBar3DSeries *> Q3DBars::seriesList() const { - dptr()->m_shared->mouseMoveEvent(event, event->pos()); + return dptrc()->m_shared->barSeriesList(); } /*! - * \internal + * \property Q3DBars::multiSeriesUniform + * + * This property controls if bars are to be scaled with proportions set to a single series bar even + * if there are multiple series displayed. If set to \c {true}, \l{barSpacing}{bar spacing} will + * affect only X-axis correctly. It is preset to \c false by default. */ -void Q3DBars::wheelEvent(QWheelEvent *event) +void Q3DBars::setMultiSeriesUniform(bool uniform) { - dptr()->m_shared->wheelEvent(event); -} - - -Q3DBarsPrivate *Q3DBars::dptr() -{ - return static_cast<Q3DBarsPrivate *>(d_ptr.data()); + if (uniform != isMultiSeriesUniform()) { + dptr()->m_shared->setMultiSeriesScaling(uniform); + emit multiSeriesUniformChanged(uniform); + } } -const Q3DBarsPrivate *Q3DBars::dptrc() const +bool Q3DBars::isMultiSeriesUniform() const { - return static_cast<const Q3DBarsPrivate *>(d_ptr.data()); + return dptrc()->m_shared->multiSeriesScaling(); } /*! @@ -220,14 +211,15 @@ const Q3DBarsPrivate *Q3DBars::dptrc() const void Q3DBars::setBarThickness(float thicknessRatio) { if (thicknessRatio != barThickness()) { - dptr()->m_shared->setBarSpecs(GLfloat(thicknessRatio), barSpacing(), isBarSpacingRelative()); + dptr()->m_shared->setBarSpecs(GLfloat(thicknessRatio), barSpacing(), + isBarSpacingRelative()); emit barThicknessChanged(thicknessRatio); } } -float Q3DBars::barThickness() +float Q3DBars::barThickness() const { - return dptr()->m_shared->barThickness(); + return dptrc()->m_shared->barThickness(); } /*! @@ -236,9 +228,9 @@ float Q3DBars::barThickness() * Bar spacing, which is the empty space between bars, in X and Z dimensions. It is preset to * \c {(1.0, 1.0)} by default. Spacing is affected by barSpacingRelative -property. * - * \sa barSpacingRelative + * \sa barSpacingRelative, multiSeriesUniform */ -void Q3DBars::setBarSpacing(QSizeF spacing) +void Q3DBars::setBarSpacing(const QSizeF &spacing) { if (spacing != barSpacing()) { dptr()->m_shared->setBarSpecs(GLfloat(barThickness()), spacing, isBarSpacingRelative()); @@ -246,9 +238,9 @@ void Q3DBars::setBarSpacing(QSizeF spacing) } } -QSizeF Q3DBars::barSpacing() +QSizeF Q3DBars::barSpacing() const { - return dptr()->m_shared->barSpacing(); + return dptrc()->m_shared->barSpacing(); } /*! @@ -266,76 +258,15 @@ void Q3DBars::setBarSpacingRelative(bool relative) } } -bool Q3DBars::isBarSpacingRelative() -{ - return dptr()->m_shared->isBarSpecRelative(); -} - -/*! - * \property Q3DBars::theme - * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DBars::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DBars::theme() const +bool Q3DBars::isBarSpacingRelative() const { - return dptrc()->m_shared->theme(); + return dptrc()->m_shared->isBarSpecRelative(); } /*! - * \property Q3DBars::selectionMode + * \property Q3DBars::rowAxis * - * Sets bar selection \a mode to a combination of \c QDataVis::SelectionFlags. It is preset to - * \c QDataVis::SelectionItem by default. - */ -void Q3DBars::setSelectionMode(QDataVis::SelectionFlags mode) -{ - dptr()->m_shared->setSelectionMode(mode); -} - -QDataVis::SelectionFlags Q3DBars::selectionMode() const -{ - return dptrc()->m_shared->selectionMode(); -} - -/*! - * \property Q3DBars::scene - * - * This property contains the read only Q3DScene that can be used to access e.g. camera object. - */ -Q3DScene *Q3DBars::scene() const -{ - return dptrc()->m_shared->scene(); -} - -/*! - * \property Q3DBars::shadowQuality - * - * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to - * \c QDataVis::ShadowQualityMedium by default. - * - * \note If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered - * until it is successful and shadowQualityChanged signal is emitted for each time the change is - * done. - */ -void Q3DBars::setShadowQuality(QDataVis::ShadowQuality quality) -{ - dptr()->m_shared->setShadowQuality(quality); -} - -QDataVis::ShadowQuality Q3DBars::shadowQuality() const -{ - return dptrc()->m_shared->shadowQuality(); -} - -/*! - * Sets a user-defined row \a axis. Implicitly calls addAxis() to transfer ownership of + * The active row \a axis. Implicitly calls addAxis() to transfer ownership of * the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels is created. @@ -343,21 +274,20 @@ QDataVis::ShadowQuality Q3DBars::shadowQuality() const * * \sa addAxis(), releaseAxis() */ -void Q3DBars::setRowAxis(Q3DCategoryAxis *axis) +void Q3DBars::setRowAxis(QCategory3DAxis *axis) { dptr()->m_shared->setAxisZ(axis); } -/*! - * \return category axis for rows. - */ -Q3DCategoryAxis *Q3DBars::rowAxis() const +QCategory3DAxis *Q3DBars::rowAxis() const { - return static_cast<Q3DCategoryAxis *>(dptrc()->m_shared->axisZ()); + return static_cast<QCategory3DAxis *>(dptrc()->m_shared->axisZ()); } /*! - * Sets a user-defined column \a axis. Implicitly calls addAxis() to transfer ownership of + * \property Q3DBars::columnAxis + * + * The active column \a axis. Implicitly calls addAxis() to transfer ownership of * the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels is created. @@ -365,21 +295,20 @@ Q3DCategoryAxis *Q3DBars::rowAxis() const * * \sa addAxis(), releaseAxis() */ -void Q3DBars::setColumnAxis(Q3DCategoryAxis *axis) +void Q3DBars::setColumnAxis(QCategory3DAxis *axis) { dptr()->m_shared->setAxisX(axis); } -/*! - * \return category axis for columns. - */ -Q3DCategoryAxis *Q3DBars::columnAxis() const +QCategory3DAxis *Q3DBars::columnAxis() const { - return static_cast<Q3DCategoryAxis *>(dptrc()->m_shared->axisX()); + return static_cast<QCategory3DAxis *>(dptrc()->m_shared->axisX()); } /*! - * Sets a user-defined value \a axis (the Y-axis). Implicitly calls addAxis() to transfer ownership + * \property Q3DBars::valueAxis + * + * The active value \a axis (the Y-axis). Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -388,17 +317,14 @@ Q3DCategoryAxis *Q3DBars::columnAxis() const * * \sa addAxis(), releaseAxis() */ -void Q3DBars::setValueAxis(Q3DValueAxis *axis) +void Q3DBars::setValueAxis(QValue3DAxis *axis) { dptr()->m_shared->setAxisY(axis); } -/*! - * \return used value axis (Y-axis). - */ -Q3DValueAxis *Q3DBars::valueAxis() const +QValue3DAxis *Q3DBars::valueAxis() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisY()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisY()); } /*! @@ -408,7 +334,7 @@ Q3DValueAxis *Q3DBars::valueAxis() const * * \sa releaseAxis(), setValueAxis(), setRowAxis(), setColumnAxis() */ -void Q3DBars::addAxis(Q3DAbstractAxis *axis) +void Q3DBars::addAxis(QAbstract3DAxis *axis) { dptr()->m_shared->addAxis(axis); } @@ -421,7 +347,7 @@ void Q3DBars::addAxis(Q3DAbstractAxis *axis) * * \sa addAxis(), setValueAxis(), setRowAxis(), setColumnAxis() */ -void Q3DBars::releaseAxis(Q3DAbstractAxis *axis) +void Q3DBars::releaseAxis(QAbstract3DAxis *axis) { dptr()->m_shared->releaseAxis(axis); } @@ -431,24 +357,43 @@ void Q3DBars::releaseAxis(Q3DAbstractAxis *axis) * * \sa addAxis() */ -QList<Q3DAbstractAxis *> Q3DBars::axes() const +QList<QAbstract3DAxis *> Q3DBars::axes() const { return dptrc()->m_shared->axes(); } +Q3DBarsPrivate *Q3DBars::dptr() +{ + return static_cast<Q3DBarsPrivate *>(d_ptr.data()); +} + +const Q3DBarsPrivate *Q3DBars::dptrc() const +{ + return static_cast<const Q3DBarsPrivate *>(d_ptr.data()); +} + Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q) - : Q3DWindowPrivate(q) + : QAbstract3DGraphPrivate(q) { } Q3DBarsPrivate::~Q3DBarsPrivate() { - delete m_shared; } -void Q3DBarsPrivate::handleShadowQualityUpdate(QDataVis::ShadowQuality quality) +void Q3DBarsPrivate::handleAxisXChanged(QAbstract3DAxis *axis) +{ + emit qptr()->columnAxisChanged(static_cast<QCategory3DAxis *>(axis)); +} + +void Q3DBarsPrivate::handleAxisYChanged(QAbstract3DAxis *axis) +{ + emit qptr()->valueAxisChanged(static_cast<QValue3DAxis *>(axis)); +} + +void Q3DBarsPrivate::handleAxisZChanged(QAbstract3DAxis *axis) { - emit qptr()->shadowQualityChanged(quality); + emit qptr()->rowAxisChanged(static_cast<QCategory3DAxis *>(axis)); } Q3DBars *Q3DBarsPrivate::qptr() @@ -456,4 +401,4 @@ Q3DBars *Q3DBarsPrivate::qptr() return static_cast<Q3DBars *>(q_ptr); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index add3b11b..06dcfedb 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,86 +19,72 @@ #ifndef Q3DBARS_H #define Q3DBARS_H -#include <QtDataVisualization/qdatavisualizationenums.h> -#include <QtDataVisualization/q3dwindow.h> -#include <QtDataVisualization/q3dtheme.h> +#include <QtDataVisualization/qabstract3dgraph.h> #include <QFont> #include <QLinearGradient> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DBarsPrivate; -class Q3DAbstractAxis; -class Q3DCategoryAxis; -class Q3DValueAxis; -class Q3DScene; +class QAbstract3DAxis; +class QCategory3DAxis; +class QValue3DAxis; class QBar3DSeries; -class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow +class QT_DATAVISUALIZATION_EXPORT Q3DBars : public QAbstract3DGraph { Q_OBJECT - Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) - Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) + Q_PROPERTY(bool multiSeriesUniform READ isMultiSeriesUniform WRITE setMultiSeriesUniform NOTIFY multiSeriesUniformChanged) Q_PROPERTY(float barThickness READ barThickness WRITE setBarThickness NOTIFY barThicknessChanged) Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing NOTIFY barSpacingChanged) Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative NOTIFY barSpacingRelativeChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) - Q_PROPERTY(Q3DScene* scene READ scene) + Q_PROPERTY(QCategory3DAxis *rowAxis READ rowAxis WRITE setRowAxis NOTIFY rowAxisChanged) + Q_PROPERTY(QCategory3DAxis *columnAxis READ columnAxis WRITE setColumnAxis NOTIFY columnAxisChanged) + Q_PROPERTY(QValue3DAxis *valueAxis READ valueAxis WRITE setValueAxis NOTIFY valueAxisChanged) + Q_PROPERTY(QBar3DSeries *primarySeries READ primarySeries WRITE setPrimarySeries NOTIFY primarySeriesChanged) public: - explicit Q3DBars(QWindow *parent = 0); + explicit Q3DBars(const QSurfaceFormat *format = 0, QWindow *parent = 0); virtual ~Q3DBars(); + void setPrimarySeries(QBar3DSeries *series); + QBar3DSeries *primarySeries() const; void addSeries(QBar3DSeries *series); void removeSeries(QBar3DSeries *series); - QList<QBar3DSeries *> seriesList(); + void insertSeries(int index, QBar3DSeries *series); + QList<QBar3DSeries *> seriesList() const; - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; + void setMultiSeriesUniform(bool uniform); + bool isMultiSeriesUniform() const; void setBarThickness(float thicknessRatio); - float barThickness(); + float barThickness() const; - void setBarSpacing(QSizeF spacing); - QSizeF barSpacing(); + void setBarSpacing(const QSizeF &spacing); + QSizeF barSpacing() const; void setBarSpacingRelative(bool relative); - bool isBarSpacingRelative(); - - void setSelectionMode(QDataVis::SelectionFlags mode); - QDataVis::SelectionFlags selectionMode() const; - - Q3DScene *scene() const; - - void setShadowQuality(QDataVis::ShadowQuality quality); - QDataVis::ShadowQuality shadowQuality() const; - - void setRowAxis(Q3DCategoryAxis *axis); - Q3DCategoryAxis *rowAxis() const; - void setColumnAxis(Q3DCategoryAxis *axis); - Q3DCategoryAxis *columnAxis() const; - void setValueAxis(Q3DValueAxis *axis); - Q3DValueAxis *valueAxis() const; - void addAxis(Q3DAbstractAxis *axis); - void releaseAxis(Q3DAbstractAxis *axis); - QList<Q3DAbstractAxis *> axes() const; + bool isBarSpacingRelative() const; + + void setRowAxis(QCategory3DAxis *axis); + QCategory3DAxis *rowAxis() const; + void setColumnAxis(QCategory3DAxis *axis); + QCategory3DAxis *columnAxis() const; + void setValueAxis(QValue3DAxis *axis); + QValue3DAxis *valueAxis() const; + void addAxis(QAbstract3DAxis *axis); + void releaseAxis(QAbstract3DAxis *axis); + QList<QAbstract3DAxis *> axes() const; signals: - void selectionModeChanged(QDataVis::SelectionFlags mode); - void shadowQualityChanged(QDataVis::ShadowQuality quality); + void multiSeriesUniformChanged(bool uniform); void barThicknessChanged(float thicknessRatio); void barSpacingChanged(QSizeF spacing); void barSpacingRelativeChanged(bool relative); - void themeChanged(Q3DTheme *theme); - -protected: - - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); + void rowAxisChanged(QCategory3DAxis *axis); + void columnAxisChanged(QCategory3DAxis *axis); + void valueAxisChanged(QValue3DAxis *axis); + void primarySeriesChanged(QBar3DSeries *series); private: Q3DBarsPrivate *dptr(); @@ -106,6 +92,6 @@ private: Q_DISABLE_COPY(Q3DBars) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/q3dbars_p.h b/src/datavisualization/engine/q3dbars_p.h index 9a059d8d..578ec57e 100644 --- a/src/datavisualization/engine/q3dbars_p.h +++ b/src/datavisualization/engine/q3dbars_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -30,28 +30,28 @@ #define Q3DBARS_P_H #include "bars3dcontroller_p.h" -#include "qdatavisualizationenums.h" -#include "q3dwindow_p.h" +#include "qabstract3dgraph_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DBars; -class Q3DBarsPrivate : public Q3DWindowPrivate +class Q3DBarsPrivate : public QAbstract3DGraphPrivate { Q_OBJECT public: Q3DBarsPrivate(Q3DBars *q); ~Q3DBarsPrivate(); - // Used to detect when shadow quality changes autonomously due to e.g. resizing. - void handleShadowQualityUpdate(QDataVis::ShadowQuality quality); + void handleAxisXChanged(QAbstract3DAxis *axis); + void handleAxisYChanged(QAbstract3DAxis *axis); + void handleAxisZChanged(QAbstract3DAxis *axis); Q3DBars *qptr(); Bars3DController *m_shared; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/q3dbox.cpp b/src/datavisualization/engine/q3dbox.cpp index cc1e0265..c5caea75 100644 --- a/src/datavisualization/engine/q3dbox.cpp +++ b/src/datavisualization/engine/q3dbox.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -20,7 +20,7 @@ #include "q3dbox.h" #include <QtCore/QList> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! \class Q3DBox @@ -411,6 +411,10 @@ Q3DBox Q3DBox::transformed(const QMatrix4x4& matrix) const #ifndef QT_NO_DEBUG_STREAM +/*! + \fn operator<<(QDebug dbg, const Q3DBox &box) + \internal + */ QDebug operator<<(QDebug dbg, const Q3DBox &box) { if (box.isFinite()) { @@ -476,6 +480,6 @@ QDataStream &operator>>(QDataStream &stream, Q3DBox &box) return stream; } -#endif // QT_NO_DATASTREAM +#endif -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dbox.h b/src/datavisualization/engine/q3dbox.h index aa63ec39..6dbaefa1 100644 --- a/src/datavisualization/engine/q3dbox.h +++ b/src/datavisualization/engine/q3dbox.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,36 +19,82 @@ #ifndef Q3DBOX_H #define Q3DBOX_H -#include <QtDataVisualization/qdatavisualizationenums.h> +#include <QtDataVisualization/qdatavisualizationglobal.h> #include <QtGui/QMatrix4x4> #include <QtGui/QVector3D> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DBox; // Needed to circumvent an issue with qdoc. If this line is removed, make docs will not work for this. class QT_DATAVISUALIZATION_EXPORT Q3DBox { public: - Q3DBox(); - Q3DBox(const QVector3D& corner1, const QVector3D& corner2); + inline Q3DBox() : boxtype(Null), mincorner(0, 0, 0), maxcorner(0, 0, 0) {} + inline Q3DBox(const QVector3D& corner1, const QVector3D& corner2): boxtype(Finite), + mincorner(qMin(corner1.x(), corner2.x()), + qMin(corner1.y(), corner2.y()), + qMin(corner1.z(), corner2.z())), + maxcorner(qMax(corner1.x(), corner2.x()), + qMax(corner1.y(), corner2.y()), + qMax(corner1.z(), corner2.z())) {} + + inline bool isNull() const { return (boxtype == Null); } + inline bool isFinite() const { return (boxtype == Finite); } + inline bool isInfinite() const { return (boxtype == Infinite); } + + inline QVector3D minimum() const { return mincorner; } + inline QVector3D maximum() const { return maxcorner; } + inline void setExtents(const QVector3D& corner1, const QVector3D& corner2) + { + boxtype = Finite; + mincorner = QVector3D(qMin(corner1.x(), corner2.x()), + qMin(corner1.y(), corner2.y()), + qMin(corner1.z(), corner2.z())); + maxcorner = QVector3D(qMax(corner1.x(), corner2.x()), + qMax(corner1.y(), corner2.y()), + qMax(corner1.z(), corner2.z())); + } - bool isNull() const; - bool isFinite() const; - bool isInfinite() const; + inline void setToNull() + { + boxtype = Null; + mincorner = QVector3D(0, 0, 0); + maxcorner = QVector3D(0, 0, 0); + } - QVector3D minimum() const; - QVector3D maximum() const; - void setExtents(const QVector3D& corner1, const QVector3D& corner2); + inline void setToInfinite() + { + boxtype = Infinite; + mincorner = QVector3D(0, 0, 0); + maxcorner = QVector3D(0, 0, 0); + } - void setToNull(); - void setToInfinite(); + inline QVector3D size() const { return maxcorner - mincorner; } + inline QVector3D center() const { return (mincorner + maxcorner) * 0.5f; } - QVector3D size() const; - QVector3D center() const; + inline bool contains(const QVector3D& point) const + { + if (boxtype == Finite) { + return (point.x() >= mincorner.x() && point.x() <= maxcorner.x() && + point.y() >= mincorner.y() && point.y() <= maxcorner.y() && + point.z() >= mincorner.z() && point.z() <= maxcorner.z()); + } else if (boxtype == Infinite) { + return true; + } else { + return false; + } + } - bool contains(const QVector3D& point) const; - bool contains(const Q3DBox& box) const; + inline bool contains(const Q3DBox& box) const + { + if (box.boxtype == Finite) + return contains(box.mincorner) && contains(box.maxcorner); + else if (box.boxtype == Infinite) + return (boxtype == Infinite); + else + return false; + } bool intersects(const Q3DBox& box) const; void intersect(const Q3DBox& box); @@ -63,8 +109,19 @@ public: void transform(const QMatrix4x4& matrix); Q3DBox transformed(const QMatrix4x4& matrix) const; - bool operator==(const Q3DBox& box) const; - bool operator!=(const Q3DBox& box) const; + inline bool operator==(const Q3DBox& box) const + { + return (boxtype == box.boxtype && + mincorner == box.mincorner && + maxcorner == box.maxcorner); + } + + inline bool operator!=(const Q3DBox& box) const + { + return (boxtype != box.boxtype || + mincorner != box.mincorner || + maxcorner != box.maxcorner); + } friend bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2); @@ -80,89 +137,6 @@ private: QVector3D mincorner, maxcorner; }; -inline Q3DBox::Q3DBox() : boxtype(Null), mincorner(0, 0, 0), maxcorner(0, 0, 0) {} - -inline Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2) - : boxtype(Finite), - mincorner(qMin(corner1.x(), corner2.x()), - qMin(corner1.y(), corner2.y()), - qMin(corner1.z(), corner2.z())), - maxcorner(qMax(corner1.x(), corner2.x()), - qMax(corner1.y(), corner2.y()), - qMax(corner1.z(), corner2.z())) {} - -inline bool Q3DBox::isNull() const { return (boxtype == Null); } -inline bool Q3DBox::isFinite() const { return (boxtype == Finite); } -inline bool Q3DBox::isInfinite() const { return (boxtype == Infinite); } - -inline QVector3D Q3DBox::minimum() const { return mincorner; } -inline QVector3D Q3DBox::maximum() const { return maxcorner; } - -inline void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2) -{ - boxtype = Finite; - mincorner = QVector3D(qMin(corner1.x(), corner2.x()), - qMin(corner1.y(), corner2.y()), - qMin(corner1.z(), corner2.z())); - maxcorner = QVector3D(qMax(corner1.x(), corner2.x()), - qMax(corner1.y(), corner2.y()), - qMax(corner1.z(), corner2.z())); -} - -inline void Q3DBox::setToNull() -{ - boxtype = Null; - mincorner = QVector3D(0, 0, 0); - maxcorner = QVector3D(0, 0, 0); -} - -inline void Q3DBox::setToInfinite() -{ - boxtype = Infinite; - mincorner = QVector3D(0, 0, 0); - maxcorner = QVector3D(0, 0, 0); -} - -inline QVector3D Q3DBox::size() const { return maxcorner - mincorner; } -inline QVector3D Q3DBox::center() const { return (mincorner + maxcorner) * 0.5f; } - -inline bool Q3DBox::contains(const QVector3D& point) const -{ - if (boxtype == Finite) { - return (point.x() >= mincorner.x() && point.x() <= maxcorner.x() && - point.y() >= mincorner.y() && point.y() <= maxcorner.y() && - point.z() >= mincorner.z() && point.z() <= maxcorner.z()); - } else if (boxtype == Infinite) { - return true; - } else { - return false; - } -} - -inline bool Q3DBox::contains(const Q3DBox& box) const -{ - if (box.boxtype == Finite) - return contains(box.mincorner) && contains(box.maxcorner); - else if (box.boxtype == Infinite) - return (boxtype == Infinite); - else - return false; -} - -inline bool Q3DBox::operator==(const Q3DBox& box) const -{ - return (boxtype == box.boxtype && - mincorner == box.mincorner && - maxcorner == box.maxcorner); -} - -inline bool Q3DBox::operator!=(const Q3DBox& box) const -{ - return (boxtype != box.boxtype || - mincorner != box.mincorner || - maxcorner != box.maxcorner); -} - inline bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2) { return box1.boxtype == box2.boxtype && @@ -179,6 +153,6 @@ QT_DATAVISUALIZATION_EXPORT QDataStream &operator<<(QDataStream &stream, const Q QT_DATAVISUALIZATION_EXPORT QDataStream &operator>>(QDataStream &stream, Q3DBox &box); #endif -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp index 6378051c..426fa51d 100644 --- a/src/datavisualization/engine/q3dcamera.cpp +++ b/src/datavisualization/engine/q3dcamera.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -26,7 +26,7 @@ #include <qmath.h> #include <QVector3D> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DCamera @@ -88,6 +88,8 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * data visualization. The class offers simple methods for setting the orbit point in rotations, * but allows also setting the 4x4 view matrix directly in case a more customized camera behavior is * needed. + * + * For Camera3D enums, see \l Q3DCamera::CameraPreset */ /*! @@ -867,5 +869,4 @@ void Q3DCameraPrivate::updateViewMatrix(float zoomAdjustment) q_ptr->setViewMatrix(viewMatrix); } - -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h index 9287e15a..1a3a3284 100644 --- a/src/datavisualization/engine/q3dcamera.h +++ b/src/datavisualization/engine/q3dcamera.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -25,7 +25,7 @@ class QVector3D; class QPoint; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DCameraPrivate; @@ -134,7 +134,6 @@ signals: void wrapYRotationChanged(bool isEnabled); private: - // To be exposed in the future void setMinXRotation(float rotation); void setMinYRotation(float rotation); void setMaxXRotation(float rotation); @@ -157,6 +156,6 @@ private: friend class QMac3DInputHandler; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DCAMERA_H +#endif diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h index ac32248e..b55010c8 100644 --- a/src/datavisualization/engine/q3dcamera_p.h +++ b/src/datavisualization/engine/q3dcamera_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,7 +32,7 @@ #include "datavisualizationglobal_p.h" #include "q3dcamera.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DCamera; @@ -82,6 +82,6 @@ public: friend class QMac3DInputHandler; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DCAMERA_P_H +#endif diff --git a/src/datavisualization/engine/q3dlight.cpp b/src/datavisualization/engine/q3dlight.cpp index bc43c3d7..8ac9e3a0 100644 --- a/src/datavisualization/engine/q3dlight.cpp +++ b/src/datavisualization/engine/q3dlight.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -20,7 +20,7 @@ #include "q3dscene.h" #include "q3dlight_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DLight @@ -79,4 +79,4 @@ void Q3DLightPrivate::sync(Q3DLight &other) } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dlight.h b/src/datavisualization/engine/q3dlight.h index f9109183..876601a7 100644 --- a/src/datavisualization/engine/q3dlight.h +++ b/src/datavisualization/engine/q3dlight.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -21,7 +21,7 @@ #include <QtDataVisualization/q3dobject.h> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DLightPrivate; class Q3DScene; @@ -43,6 +43,6 @@ private: friend class Q3DScenePrivate; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DLIGHT_H +#endif diff --git a/src/datavisualization/engine/q3dlight_p.h b/src/datavisualization/engine/q3dlight_p.h index dad6d670..5cf979f0 100644 --- a/src/datavisualization/engine/q3dlight_p.h +++ b/src/datavisualization/engine/q3dlight_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,7 +32,7 @@ #include "datavisualizationglobal_p.h" #include "q3dlight.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DScene; class Q3DLight; @@ -49,9 +49,9 @@ public: Q3DLight *q_ptr; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DLIGHT_P_H +#endif diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp index c4098fd0..cda4a370 100644 --- a/src/datavisualization/engine/q3dobject.cpp +++ b/src/datavisualization/engine/q3dobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -18,9 +18,9 @@ #include "q3dobject.h" #include "q3dobject_p.h" -#include "q3dscene.h" +#include "q3dscene_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! \class Q3DObject @@ -97,6 +97,8 @@ void Q3DObject::setPosition(const QVector3D &position) void Q3DObject::setDirty(bool dirty) { d_ptr->m_isDirty = dirty; + if (parentScene()) + parentScene()->d_ptr->m_sceneDirty = true; } /*! @@ -118,4 +120,4 @@ Q3DObjectPrivate::~Q3DObjectPrivate() } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h index b5ce7804..07506f63 100644 --- a/src/datavisualization/engine/q3dobject.h +++ b/src/datavisualization/engine/q3dobject.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,13 +19,12 @@ #ifndef Q3DOBJECT_H #define Q3DOBJECT_H -#include <QtDataVisualization/qdatavisualizationenums.h> #include <QtDataVisualization/q3dscene.h> #include <QObject> #include <QVector3D> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DObjectPrivate; @@ -61,6 +60,6 @@ private: friend class Q3DScenePrivate; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DOBJECT_H +#endif diff --git a/src/datavisualization/engine/q3dobject_p.h b/src/datavisualization/engine/q3dobject_p.h index bac18cfe..6c4809fd 100644 --- a/src/datavisualization/engine/q3dobject_p.h +++ b/src/datavisualization/engine/q3dobject_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -31,7 +31,7 @@ #include "datavisualizationglobal_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DObject; class Q3DScene; @@ -48,6 +48,6 @@ public: bool m_isDirty; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DOBJECT_P_H +#endif diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp index 3c28b4a5..db7d2491 100644 --- a/src/datavisualization/engine/q3dscatter.cpp +++ b/src/datavisualization/engine/q3dscatter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,13 +19,11 @@ #include "q3dscatter.h" #include "q3dscatter_p.h" #include "scatter3dcontroller_p.h" -#include "q3dvalueaxis.h" +#include "qvalue3daxis.h" #include "q3dcamera.h" #include "qscatter3dseries_p.h" -#include <QMouseEvent> - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DScatter @@ -80,24 +78,15 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! - * Constructs a new 3D scatter graph with optional \a parent window. + * Constructs a new 3D scatter graph with optional \a parent window + * and surface \a format. */ -Q3DScatter::Q3DScatter(QWindow *parent) - : Q3DWindow(new Q3DScatterPrivate(this), parent) +Q3DScatter::Q3DScatter(const QSurfaceFormat *format, QWindow *parent) + : QAbstract3DGraph(new Q3DScatterPrivate(this), format, parent) { dptr()->m_shared = new Scatter3DController(geometry()); d_ptr->setVisualController(dptr()->m_shared); dptr()->m_shared->initializeOpenGL(); - QObject::connect(dptr()->m_shared, &Abstract3DController::selectionModeChanged, this, - &Q3DScatter::selectionModeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, - &Q3DScatter::shadowQualityChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DScatter::themeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), - &Q3DWindowPrivate::renderLater); - QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, dptr(), - &Q3DScatterPrivate::handleShadowQualityUpdate); } /*! @@ -128,57 +117,9 @@ void Q3DScatter::removeSeries(QScatter3DSeries *series) /*! * \return list of series added to this graph. */ -QList<QScatter3DSeries *> Q3DScatter::seriesList() -{ - return dptr()->m_shared->scatterSeriesList(); -} - -/*! - * \internal - */ -void Q3DScatter::mouseDoubleClickEvent(QMouseEvent *event) -{ - dptr()->m_shared->mouseDoubleClickEvent(event); -} - -/*! - * \internal - */ -void Q3DScatter::touchEvent(QTouchEvent *event) -{ - dptr()->m_shared->touchEvent(event); -} - -/*! - * \internal - */ -void Q3DScatter::mousePressEvent(QMouseEvent *event) -{ - dptr()->m_shared->mousePressEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DScatter::mouseReleaseEvent(QMouseEvent *event) +QList<QScatter3DSeries *> Q3DScatter::seriesList() const { - dptr()->m_shared->mouseReleaseEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DScatter::mouseMoveEvent(QMouseEvent *event) -{ - dptr()->m_shared->mouseMoveEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DScatter::wheelEvent(QWheelEvent *event) -{ - dptr()->m_shared->wheelEvent(event); + return dptrc()->m_shared->scatterSeriesList(); } Q3DScatterPrivate *Q3DScatter::dptr() @@ -192,72 +133,9 @@ const Q3DScatterPrivate *Q3DScatter::dptrc() const } /*! - * \property Q3DScatter::theme - * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DScatter::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DScatter::theme() const -{ - return dptrc()->m_shared->theme(); -} - -/*! - * \property Q3DScatter::selectionMode - * - * Sets item selection \a mode to a combination of \c QDataVis::SelectionFlags. It is preset to - * \c QDataVis::SelectionItem by default. + * \property Q3DScatter::axisX * - * \note Only \c QDataVis::SelectionItem and \c QDataVis::SelectionNone are supported. - */ -void Q3DScatter::setSelectionMode(QDataVis::SelectionFlags mode) -{ - dptr()->m_shared->setSelectionMode(mode); -} - -QDataVis::SelectionFlags Q3DScatter::selectionMode() const -{ - return dptrc()->m_shared->selectionMode(); -} - -/*! - * \property Q3DScatter::scene - * - * This property contains the read only Q3DScene that can be used to access e.g. camera object. - */ -Q3DScene *Q3DScatter::scene() const -{ - return dptrc()->m_shared->scene(); -} - -/*! - * \property Q3DScatter::shadowQuality - * - * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to - * \c QDataVis::ShadowQualityMedium by default. - * - * \note If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered - * until it is successful and shadowQualityChanged signal is emitted for each time the change is - * done. - */ -void Q3DScatter::setShadowQuality(QDataVis::ShadowQuality quality) -{ - return dptr()->m_shared->setShadowQuality(quality); -} - -QDataVis::ShadowQuality Q3DScatter::shadowQuality() const -{ - return dptrc()->m_shared->shadowQuality(); -} - -/*! - * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership + * The active X-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -266,21 +144,20 @@ QDataVis::ShadowQuality Q3DScatter::shadowQuality() const * * \sa addAxis(), releaseAxis() */ -void Q3DScatter::setAxisX(Q3DValueAxis *axis) +void Q3DScatter::setAxisX(QValue3DAxis *axis) { dptr()->m_shared->setAxisX(axis); } -/*! - * \return used X-axis. - */ -Q3DValueAxis *Q3DScatter::axisX() const +QValue3DAxis *Q3DScatter::axisX() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisX()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisX()); } /*! - * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership + * \property Q3DScatter::axisY + * + * The active Y-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -289,21 +166,20 @@ Q3DValueAxis *Q3DScatter::axisX() const * * \sa addAxis(), releaseAxis() */ -void Q3DScatter::setAxisY(Q3DValueAxis *axis) +void Q3DScatter::setAxisY(QValue3DAxis *axis) { dptr()->m_shared->setAxisY(axis); } -/*! - * \return used Y-axis. - */ -Q3DValueAxis *Q3DScatter::axisY() const +QValue3DAxis *Q3DScatter::axisY() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisY()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisY()); } /*! - * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership + * \property Q3DScatter::axisZ + * + * The active Z-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -312,7 +188,7 @@ Q3DValueAxis *Q3DScatter::axisY() const * * \sa addAxis(), releaseAxis() */ -void Q3DScatter::setAxisZ(Q3DValueAxis *axis) +void Q3DScatter::setAxisZ(QValue3DAxis *axis) { dptr()->m_shared->setAxisZ(axis); } @@ -320,9 +196,9 @@ void Q3DScatter::setAxisZ(Q3DValueAxis *axis) /*! * \return used Z-axis. */ -Q3DValueAxis *Q3DScatter::axisZ() const +QValue3DAxis *Q3DScatter::axisZ() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisZ()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisZ()); } /*! @@ -332,7 +208,7 @@ Q3DValueAxis *Q3DScatter::axisZ() const * * \sa releaseAxis(), setAxisX(), setAxisY(), setAxisZ() */ -void Q3DScatter::addAxis(Q3DValueAxis *axis) +void Q3DScatter::addAxis(QValue3DAxis *axis) { dptr()->m_shared->addAxis(axis); } @@ -345,7 +221,7 @@ void Q3DScatter::addAxis(Q3DValueAxis *axis) * * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ() */ -void Q3DScatter::releaseAxis(Q3DValueAxis *axis) +void Q3DScatter::releaseAxis(QValue3DAxis *axis) { dptr()->m_shared->releaseAxis(axis); } @@ -355,35 +231,38 @@ void Q3DScatter::releaseAxis(Q3DValueAxis *axis) * * \sa addAxis() */ -QList<Q3DValueAxis *> Q3DScatter::axes() const +QList<QValue3DAxis *> Q3DScatter::axes() const { - QList<Q3DAbstractAxis *> abstractAxes = dptrc()->m_shared->axes(); - QList<Q3DValueAxis *> retList; - foreach (Q3DAbstractAxis *axis, abstractAxes) - retList.append(static_cast<Q3DValueAxis *>(axis)); + QList<QAbstract3DAxis *> abstractAxes = dptrc()->m_shared->axes(); + QList<QValue3DAxis *> retList; + foreach (QAbstract3DAxis *axis, abstractAxes) + retList.append(static_cast<QValue3DAxis *>(axis)); return retList; } -/*! - * \fn void Q3DScatter::shadowQualityChanged(QDataVis::ShadowQuality quality) - * - * This signal is emitted when shadow \a quality changes. - */ - Q3DScatterPrivate::Q3DScatterPrivate(Q3DScatter *q) - : Q3DWindowPrivate(q) + : QAbstract3DGraphPrivate(q) { } Q3DScatterPrivate::~Q3DScatterPrivate() { - delete m_shared; } -void Q3DScatterPrivate::handleShadowQualityUpdate(QDataVis::ShadowQuality quality) +void Q3DScatterPrivate::handleAxisXChanged(QAbstract3DAxis *axis) +{ + emit qptr()->axisXChanged(static_cast<QValue3DAxis *>(axis)); +} + +void Q3DScatterPrivate::handleAxisYChanged(QAbstract3DAxis *axis) +{ + emit qptr()->axisYChanged(static_cast<QValue3DAxis *>(axis)); +} + +void Q3DScatterPrivate::handleAxisZChanged(QAbstract3DAxis *axis) { - emit qptr()->shadowQualityChanged(quality); + emit qptr()->axisZChanged(static_cast<QValue3DAxis *>(axis)); } Q3DScatter *Q3DScatterPrivate::qptr() @@ -391,5 +270,5 @@ Q3DScatter *Q3DScatterPrivate::qptr() return static_cast<Q3DScatter *>(q_ptr); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h index e58146a1..55158537 100644 --- a/src/datavisualization/engine/q3dscatter.h +++ b/src/datavisualization/engine/q3dscatter.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,71 +19,47 @@ #ifndef Q3DSCATTER_H #define Q3DSCATTER_H -#include <QtDataVisualization/qdatavisualizationenums.h> -#include <QtDataVisualization/q3dwindow.h> +#include <QtDataVisualization/qabstract3dgraph.h> #include <QtDataVisualization/q3dscene.h> -#include <QtDataVisualization/q3dtheme.h> #include <QFont> #include <QLinearGradient> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DScatterPrivate; -class LabelItem; -class Q3DValueAxis; -class Q3DCategoryAxis; +class QValue3DAxis; +class QCategory3DAxis; class QScatter3DSeries; -class Q3DTheme; -class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow +class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public QAbstract3DGraph { Q_OBJECT - Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) - Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) - Q_PROPERTY(Q3DScene* scene READ scene) + Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged) + Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged) + Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged) public: - explicit Q3DScatter(QWindow *parent = 0); + explicit Q3DScatter(const QSurfaceFormat *format = 0, QWindow *parent = 0); virtual ~Q3DScatter(); void addSeries(QScatter3DSeries *series); void removeSeries(QScatter3DSeries *series); - QList<QScatter3DSeries *> seriesList(); - - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; - - void setSelectionMode(QDataVis::SelectionFlags mode); - QDataVis::SelectionFlags selectionMode() const; - - Q3DScene *scene() const; - - void setShadowQuality(QDataVis::ShadowQuality quality); - QDataVis::ShadowQuality shadowQuality() const; - - void setAxisX(Q3DValueAxis *axis); - Q3DValueAxis *axisX() const; - void setAxisY(Q3DValueAxis *axis); - Q3DValueAxis *axisY() const; - void setAxisZ(Q3DValueAxis *axis); - Q3DValueAxis *axisZ() const; - void addAxis(Q3DValueAxis *axis); - void releaseAxis(Q3DValueAxis *axis); - QList<Q3DValueAxis *> axes() const; + QList<QScatter3DSeries *> seriesList() const; + + void setAxisX(QValue3DAxis *axis); + QValue3DAxis *axisX() const; + void setAxisY(QValue3DAxis *axis); + QValue3DAxis *axisY() const; + void setAxisZ(QValue3DAxis *axis); + QValue3DAxis *axisZ() const; + void addAxis(QValue3DAxis *axis); + void releaseAxis(QValue3DAxis *axis); + QList<QValue3DAxis *> axes() const; signals: - void selectionModeChanged(QDataVis::SelectionFlags mode); - void shadowQualityChanged(QDataVis::ShadowQuality quality); - void themeChanged(Q3DTheme* theme); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); + void axisXChanged(QValue3DAxis *axis); + void axisYChanged(QValue3DAxis *axis); + void axisZChanged(QValue3DAxis *axis); private: Q3DScatterPrivate *dptr(); @@ -91,6 +67,6 @@ private: Q_DISABLE_COPY(Q3DScatter) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/q3dscatter_p.h b/src/datavisualization/engine/q3dscatter_p.h index d65776c5..0703220b 100644 --- a/src/datavisualization/engine/q3dscatter_p.h +++ b/src/datavisualization/engine/q3dscatter_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -30,28 +30,28 @@ #define Q3DSCATTER_P_H #include "scatter3dcontroller_p.h" -#include "qdatavisualizationenums.h" -#include "q3dwindow_p.h" +#include "qabstract3dgraph_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DScatter; -class Q3DScatterPrivate : public Q3DWindowPrivate +class Q3DScatterPrivate : public QAbstract3DGraphPrivate { Q_OBJECT public: Q3DScatterPrivate(Q3DScatter *q); ~Q3DScatterPrivate(); - // Used to detect when shadow quality changes autonomously due to e.g. resizing. - void handleShadowQualityUpdate(QDataVis::ShadowQuality quality); + void handleAxisXChanged(QAbstract3DAxis *axis); + void handleAxisYChanged(QAbstract3DAxis *axis); + void handleAxisZChanged(QAbstract3DAxis *axis); Q3DScatter *qptr(); Scatter3DController *m_shared; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp index d8104b3a..6ee4e275 100644 --- a/src/datavisualization/engine/q3dscene.cpp +++ b/src/datavisualization/engine/q3dscene.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -25,7 +25,7 @@ #include "q3dcamera_p.h" #include "q3dlight_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DScene @@ -47,6 +47,11 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! + * \class Q3DSceneChangeBitField + * \internal + */ + +/*! * \qmltype Scene3D * \inqmlmodule QtDataVisualization * \since QtDataVisualization 1.0 @@ -90,9 +95,9 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * \qmlproperty point Scene3D::selectionQueryPosition * * This property contains the coordinates for the user input that should be processed - * by the scene as selection. If this is set to value other than \c{(-1, -1)} the + * by the scene as selection. If this is set to value other than invalidSelectionPoint the * graph tries to select a data item at the given point within the primary viewport. - * After the rendering pass the property is returned to its default state of \c{(-1, -1)}. + * After the rendering pass the property is returned to its default state of invalidSelectionPoint. */ /*! @@ -131,6 +136,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! + * \qmlproperty point Scene3D::invalidSelectionPoint + * A constant property providing an invalid point for selection. + */ + + +/*! * Constructs a basic scene with one light and one camera in it. An * optional \a parent parameter can be given and is then passed to QObject constructor. */ @@ -179,6 +190,8 @@ void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport) d_ptr->m_primarySubViewport = intersectedViewport; d_ptr->updateGLSubViewports(); d_ptr->m_changeTracker.primarySubViewportChanged = true; + d_ptr->m_sceneDirty = true; + emit primarySubViewportChanged(intersectedViewport); emit d_ptr->needRender(); } @@ -186,38 +199,32 @@ void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport) /*! * Returns whether the given \a point resides inside the primary subview or not. - * The method takes care of correctly mapping between OpenGL coordinates used in the - * viewport definitions and the Qt event coordinate system used in the input system. * \return \c true if the point is inside the primary subview. */ bool Q3DScene::isPointInPrimarySubView(const QPoint &point) { - // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently. int x = point.x(); int y = point.y(); int areaMinX = d_ptr->m_primarySubViewport.x(); - int areaMaxX = d_ptr->m_viewport.x() + d_ptr->m_primarySubViewport.x() + d_ptr->m_primarySubViewport.width(); - int areaMaxY = d_ptr->m_viewport.y() + d_ptr->m_primarySubViewport.y() + d_ptr->m_primarySubViewport.height(); - int areaMinY = d_ptr->m_viewport.y() + d_ptr->m_primarySubViewport.y(); + int areaMaxX = d_ptr->m_primarySubViewport.x() + d_ptr->m_primarySubViewport.width(); + int areaMinY = d_ptr->m_primarySubViewport.y(); + int areaMaxY = d_ptr->m_primarySubViewport.y() + d_ptr->m_primarySubViewport.height(); return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY ); } /*! * Returns whether the given \a point resides inside the secondary subview or not. - * The method takes care of correctly mapping between OpenGL coordinates used in the - * viewport definitions and the Qt event coordinate system used in the input system. * \return \c true if the point is inside the secondary subview. */ bool Q3DScene::isPointInSecondarySubView(const QPoint &point) { - // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently. int x = point.x(); int y = point.y(); int areaMinX = d_ptr->m_secondarySubViewport.x(); - int areaMaxX = d_ptr->m_viewport.x() + d_ptr->m_secondarySubViewport.x() + d_ptr->m_secondarySubViewport.width(); - int areaMaxY = d_ptr->m_viewport.y() + d_ptr->m_secondarySubViewport.y() + d_ptr->m_secondarySubViewport.height(); - int areaMinY = d_ptr->m_viewport.y() + d_ptr->m_secondarySubViewport.y(); + int areaMaxX = d_ptr->m_secondarySubViewport.x() + d_ptr->m_secondarySubViewport.width(); + int areaMinY = d_ptr->m_secondarySubViewport.y(); + int areaMaxY = d_ptr->m_secondarySubViewport.y() + d_ptr->m_secondarySubViewport.height(); return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY ); } @@ -241,6 +248,8 @@ void Q3DScene::setSecondarySubViewport(const QRect &secondarySubViewport) d_ptr->m_secondarySubViewport = intersectedViewport; d_ptr->updateGLSubViewports(); d_ptr->m_changeTracker.secondarySubViewportChanged = true; + d_ptr->m_sceneDirty = true; + emit secondarySubViewportChanged(intersectedViewport); emit d_ptr->needRender(); } @@ -259,6 +268,8 @@ void Q3DScene::setSelectionQueryPosition(const QPoint &point) if (point != d_ptr->m_selectionQueryPosition) { d_ptr->m_selectionQueryPosition = point; d_ptr->m_changeTracker.selectionQueryPositionChanged = true; + d_ptr->m_sceneDirty = true; + emit selectionQueryPositionChanged(point); emit d_ptr->needRender(); } @@ -272,7 +283,7 @@ QPoint Q3DScene::selectionQueryPosition() const /*! * \return a QPoint signifying an invalid selection position. */ -const QPoint Q3DScene::invalidSelectionPoint() +QPoint Q3DScene::invalidSelectionPoint() { static const QPoint invalidSelectionPos(-1, -1); return invalidSelectionPos; @@ -294,6 +305,8 @@ void Q3DScene::setSlicingActive(bool isSlicing) if (d_ptr->m_isSlicingActive != isSlicing) { d_ptr->m_isSlicingActive = isSlicing; d_ptr->m_changeTracker.slicingActivatedChanged = true; + d_ptr->m_sceneDirty = true; + d_ptr->calculateSubViewports(); emit slicingActiveChanged(isSlicing); emit d_ptr->needRender(); @@ -316,6 +329,8 @@ void Q3DScene::setSecondarySubviewOnTop(bool isSecondaryOnTop) if (d_ptr->m_isSecondarySubviewOnTop != isSecondaryOnTop) { d_ptr->m_isSecondarySubviewOnTop = isSecondaryOnTop; d_ptr->m_changeTracker.subViewportOrderChanged = true; + d_ptr->m_sceneDirty = true; + emit secondarySubviewOnTopChanged(isSecondaryOnTop); emit d_ptr->needRender(); } @@ -353,6 +368,8 @@ void Q3DScene::setActiveCamera(Q3DCamera *camera) d_ptr->m_camera = camera; d_ptr->m_changeTracker.cameraChanged = true; + d_ptr->m_sceneDirty = true; + if (camera) { connect(camera, &Q3DCamera::xRotationChanged, d_ptr.data(), @@ -391,6 +408,8 @@ void Q3DScene::setActiveLight(Q3DLight *light) if (light != d_ptr->m_light) { d_ptr->m_light = light; d_ptr->m_changeTracker.lightChanged = true; + d_ptr->m_sceneDirty = true; + emit activeLightChanged(light); } } @@ -411,6 +430,8 @@ void Q3DScene::setDevicePixelRatio(float pixelRatio) if (d_ptr->m_devicePixelRatio != pixelRatio) { d_ptr->m_devicePixelRatio = pixelRatio; d_ptr->m_changeTracker.devicePixelRatioChanged = true; + d_ptr->m_sceneDirty = true; + emit devicePixelRatioChanged(pixelRatio); d_ptr->updateGLViewport(); emit d_ptr->needRender(); @@ -512,6 +533,9 @@ void Q3DScenePrivate::sync(Q3DScenePrivate &other) m_changeTracker.devicePixelRatioChanged = false; other.m_changeTracker.devicePixelRatioChanged = false; } + + m_sceneDirty = false; + other.m_sceneDirty = false; } void Q3DScenePrivate::setViewport(const QRect &viewport) @@ -547,6 +571,7 @@ void Q3DScenePrivate::setWindowSize(const QSize &size) m_windowSize = size; updateGLViewport(); m_changeTracker.windowSizeChanged = true; + m_sceneDirty = true; emit needRender(); } } @@ -562,9 +587,9 @@ void Q3DScenePrivate::calculateSubViewports() const float smallerViewPortRatio = 0.2f; if (m_isSlicingActive) { q_ptr->setPrimarySubViewport(QRect(0, - 0, - m_viewport.width() * smallerViewPortRatio, - m_viewport.height() * smallerViewPortRatio)); + 0, + m_viewport.width() * smallerViewPortRatio, + m_viewport.height() * smallerViewPortRatio)); q_ptr->setSecondarySubViewport(QRect(0, 0, m_viewport.width(), m_viewport.height())); } else { q_ptr->setPrimarySubViewport(QRect(0, 0, m_viewport.width(), m_viewport.height())); @@ -578,11 +603,13 @@ void Q3DScenePrivate::updateGLViewport() { // Update GL viewport m_glViewport.setX(m_viewport.x() * m_devicePixelRatio); - m_glViewport.setY((m_windowSize.height() - (m_viewport.y() + m_viewport.height())) * m_devicePixelRatio); + m_glViewport.setY((m_windowSize.height() - (m_viewport.y() + m_viewport.height())) + * m_devicePixelRatio); m_glViewport.setWidth(m_viewport.width() * m_devicePixelRatio); m_glViewport.setHeight(m_viewport.height() * m_devicePixelRatio); m_changeTracker.viewportChanged = true; + m_sceneDirty = true; // Do default subviewport changes first, then allow signal listeners to override. updateGLSubViewports(); @@ -592,12 +619,18 @@ void Q3DScenePrivate::updateGLViewport() void Q3DScenePrivate::updateGLSubViewports() { m_glPrimarySubViewport.setX((m_primarySubViewport.x() + m_viewport.x()) * m_devicePixelRatio); - m_glPrimarySubViewport.setY((m_windowSize.height() - (m_primarySubViewport.y() + m_viewport.y() + m_primarySubViewport.height())) * m_devicePixelRatio); + m_glPrimarySubViewport.setY((m_windowSize.height() - (m_primarySubViewport.y() + m_viewport.y() + + m_primarySubViewport.height())) + * m_devicePixelRatio); m_glPrimarySubViewport.setWidth(m_primarySubViewport.width() * m_devicePixelRatio); m_glPrimarySubViewport.setHeight(m_primarySubViewport.height() * m_devicePixelRatio); - m_glSecondarySubViewport.setX(m_secondarySubViewport.x() * m_devicePixelRatio); - m_glSecondarySubViewport.setY((m_windowSize.height() - (m_secondarySubViewport.y() + m_viewport.y() + m_secondarySubViewport.height())) * m_devicePixelRatio); + m_glSecondarySubViewport.setX((m_secondarySubViewport.x() + m_viewport.x()) + * m_devicePixelRatio); + m_glSecondarySubViewport.setY((m_windowSize.height() - (m_secondarySubViewport.y() + + m_viewport.y() + + m_secondarySubViewport.height())) + * m_devicePixelRatio); m_glSecondarySubViewport.setWidth(m_secondarySubViewport.width() * m_devicePixelRatio); m_glSecondarySubViewport.setHeight(m_secondarySubViewport.height() * m_devicePixelRatio); } @@ -617,4 +650,4 @@ QRect Q3DScenePrivate::glSecondarySubViewport() return m_glSecondarySubViewport; } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h index b0dadff9..61a18c9d 100644 --- a/src/datavisualization/engine/q3dscene.h +++ b/src/datavisualization/engine/q3dscene.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,11 +19,12 @@ #ifndef Q3DSCENE_H #define Q3DSCENE_H -#include <QtDataVisualization/qdatavisualizationenums.h> +#include <QtDataVisualization/qdatavisualizationglobal.h> + #include <QObject> #include <QRect> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DCamera; class Q3DBox; @@ -59,7 +60,7 @@ public: void setSelectionQueryPosition(const QPoint &point); QPoint selectionQueryPosition() const; - static const QPoint invalidSelectionPoint(); + static QPoint invalidSelectionPoint(); void setSlicingActive(bool isSlicing); bool isSlicingActive() const; @@ -96,7 +97,7 @@ private: Q_DISABLE_COPY(Q3DScene) friend class AbstractDeclarative; - friend class Q3DWindow; + friend class QAbstract3DGraph; friend class Abstract3DController; friend class Q3DScenePrivate; friend class Abstract3DRenderer; @@ -104,8 +105,9 @@ private: friend class Surface3DRenderer; friend class Scatter3DRenderer; friend class Q3DCameraPrivate; + friend class Q3DObject; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DSCENE_H +#endif diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h index c9d9d1f6..be0d3dc5 100644 --- a/src/datavisualization/engine/q3dscene_p.h +++ b/src/datavisualization/engine/q3dscene_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,7 +32,7 @@ #include "datavisualizationglobal_p.h" #include <QRect> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DCamera; class Q3DLight; @@ -107,8 +107,9 @@ public: QRect m_glViewport; QRect m_glPrimarySubViewport; QRect m_glSecondarySubViewport; + bool m_sceneDirty; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DSCENE_P_H +#endif diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp index ce738685..a8a8235e 100644 --- a/src/datavisualization/engine/q3dsurface.cpp +++ b/src/datavisualization/engine/q3dsurface.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -18,14 +18,12 @@ #include "q3dsurface.h" #include "q3dsurface_p.h" -#include "q3dvalueaxis.h" +#include "qvalue3daxis.h" #include "qsurfacedataproxy.h" #include "q3dcamera.h" #include "qsurface3dseries_p.h" -#include <QMouseEvent> - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \class Q3DSurface @@ -42,7 +40,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * The selection pointer is accompanied with a label which in default case shows the value of the * data point and the coordinates of the point. * - * The value range and the label format shown on the axis can be controlled through Q3DValueAxis. + * The value range and the label format shown on the axis can be controlled through QValue3DAxis. * * To rotate the graph, hold down the right mouse button and move the mouse. Zooming is done using mouse * wheel. Both assume the default input handler is in use. @@ -93,22 +91,15 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! - * Constructs a new 3D surface graph with optional \a parent window. + * Constructs a new 3D surface graph with optional \a parent window + * and surface \a format. */ -Q3DSurface::Q3DSurface(QWindow *parent) - : Q3DWindow(new Q3DSurfacePrivate(this), parent) +Q3DSurface::Q3DSurface(const QSurfaceFormat *format, QWindow *parent) + : QAbstract3DGraph(new Q3DSurfacePrivate(this), format, parent) { dptr()->m_shared = new Surface3DController(geometry()); d_ptr->setVisualController(dptr()->m_shared); dptr()->m_shared->initializeOpenGL(); - QObject::connect(dptr()->m_shared, &Abstract3DController::selectionModeChanged, this, - &Q3DSurface::selectionModeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::themeChanged, this, - &Q3DSurface::themeChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::shadowQualityChanged, this, - &Q3DSurface::shadowQualityChanged); - QObject::connect(dptr()->m_shared, &Abstract3DController::needRender, d_ptr.data(), - &Q3DWindowPrivate::renderLater); } /*! @@ -141,57 +132,9 @@ void Q3DSurface::removeSeries(QSurface3DSeries *series) * * \note The surface graph currently supports only a single series at a time. */ -QList<QSurface3DSeries *> Q3DSurface::seriesList() -{ - return dptr()->m_shared->surfaceSeriesList(); -} - -/*! - * \internal - */ -void Q3DSurface::mouseDoubleClickEvent(QMouseEvent *event) -{ - dptr()->m_shared->mouseDoubleClickEvent(event); -} - -/*! - * \internal - */ -void Q3DSurface::touchEvent(QTouchEvent *event) -{ - dptr()->m_shared->touchEvent(event); -} - -/*! - * \internal - */ -void Q3DSurface::mousePressEvent(QMouseEvent *event) -{ - dptr()->m_shared->mousePressEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DSurface::mouseReleaseEvent(QMouseEvent *event) -{ - dptr()->m_shared->mouseReleaseEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DSurface::mouseMoveEvent(QMouseEvent *event) +QList<QSurface3DSeries *> Q3DSurface::seriesList() const { - dptr()->m_shared->mouseMoveEvent(event, event->pos()); -} - -/*! - * \internal - */ -void Q3DSurface::wheelEvent(QWheelEvent *event) -{ - dptr()->m_shared->wheelEvent(event); + return dptrc()->m_shared->surfaceSeriesList(); } Q3DSurfacePrivate *Q3DSurface::dptr() @@ -205,71 +148,9 @@ const Q3DSurfacePrivate *Q3DSurface::dptrc() const } /*! - * \property Q3DSurface::theme + * \property Q3DSurface::axisX * - * A \a theme to be used for the graph. Ownership of the \a theme is transferred. Previous theme - * is deleted when a new one is set. Properties of the \a theme can be modified even after setting - * it, and the modifications take effect immediately. - */ -void Q3DSurface::setTheme(Q3DTheme *theme) -{ - dptr()->m_shared->setTheme(theme); -} - -Q3DTheme *Q3DSurface::theme() const -{ - return dptrc()->m_shared->theme(); -} - -/*! - * \property Q3DSurface::shadowQuality - * - * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to - * \c QDataVis::ShadowQualityMedium by default. - * - * \note If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered - * until it is successful and shadowQualityChanged signal is emitted for each time the change is - * done. - */ -void Q3DSurface::setShadowQuality(QDataVis::ShadowQuality quality) -{ - return dptr()->m_shared->setShadowQuality(quality); -} - -QDataVis::ShadowQuality Q3DSurface::shadowQuality() const -{ - return dptrc()->m_shared->shadowQuality(); -} - -/*! - * \property Q3DSurface::selectionMode - * - * Sets point selection \a mode to a combination of \c QDataVis::SelectionFlags. Surface supports - * \c SelectionItem and \c SelectionSlice with either \c SelectionRow or \c SelectionColumn. - * It is preset to \c SelectionItem by default. - */ -void Q3DSurface::setSelectionMode(QDataVis::SelectionFlags mode) -{ - dptr()->m_shared->setSelectionMode(mode); -} - -QDataVis::SelectionFlags Q3DSurface::selectionMode() const -{ - return dptrc()->m_shared->selectionMode(); -} - -/*! - * \property Q3DSurface::scene - * - * This property contains the read only Q3DScene that can be used to access, for example, a camera object. - */ -Q3DScene *Q3DSurface::scene() const -{ - return dptrc()->m_shared->scene(); -} - -/*! - * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership + * The active X-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -278,7 +159,7 @@ Q3DScene *Q3DSurface::scene() const * * \sa addAxis(), releaseAxis() */ -void Q3DSurface::setAxisX(Q3DValueAxis *axis) +void Q3DSurface::setAxisX(QValue3DAxis *axis) { dptr()->m_shared->setAxisX(axis); } @@ -286,13 +167,15 @@ void Q3DSurface::setAxisX(Q3DValueAxis *axis) /*! * \return used X-axis. */ -Q3DValueAxis *Q3DSurface::axisX() const +QValue3DAxis *Q3DSurface::axisX() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisX()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisX()); } /*! - * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership + * \property Q3DSurface::axisY + * + * The active Y-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -301,7 +184,7 @@ Q3DValueAxis *Q3DSurface::axisX() const * * \sa addAxis(), releaseAxis() */ -void Q3DSurface::setAxisY(Q3DValueAxis *axis) +void Q3DSurface::setAxisY(QValue3DAxis *axis) { dptr()->m_shared->setAxisY(axis); } @@ -309,13 +192,15 @@ void Q3DSurface::setAxisY(Q3DValueAxis *axis) /*! * \return used Y-axis. */ -Q3DValueAxis *Q3DSurface::axisY() const +QValue3DAxis *Q3DSurface::axisY() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisY()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisY()); } /*! - * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership + * \property Q3DSurface::axisZ + * + * The active Z-axis. Implicitly calls addAxis() to transfer ownership * of the \a axis to this graph. * * If the \a axis is null, a temporary default axis with no labels and automatically adjusting @@ -324,7 +209,7 @@ Q3DValueAxis *Q3DSurface::axisY() const * * \sa addAxis(), releaseAxis() */ -void Q3DSurface::setAxisZ(Q3DValueAxis *axis) +void Q3DSurface::setAxisZ(QValue3DAxis *axis) { dptr()->m_shared->setAxisZ(axis); } @@ -332,9 +217,9 @@ void Q3DSurface::setAxisZ(Q3DValueAxis *axis) /*! * \return used Z-axis. */ -Q3DValueAxis *Q3DSurface::axisZ() const +QValue3DAxis *Q3DSurface::axisZ() const { - return static_cast<Q3DValueAxis *>(dptrc()->m_shared->axisZ()); + return static_cast<QValue3DAxis *>(dptrc()->m_shared->axisZ()); } /*! @@ -344,7 +229,7 @@ Q3DValueAxis *Q3DSurface::axisZ() const * * \sa releaseAxis(), setAxisX(), setAxisY(), setAxisZ() */ -void Q3DSurface::addAxis(Q3DValueAxis *axis) +void Q3DSurface::addAxis(QValue3DAxis *axis) { dptr()->m_shared->addAxis(axis); } @@ -357,7 +242,7 @@ void Q3DSurface::addAxis(Q3DValueAxis *axis) * * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ() */ -void Q3DSurface::releaseAxis(Q3DValueAxis *axis) +void Q3DSurface::releaseAxis(QValue3DAxis *axis) { dptr()->m_shared->releaseAxis(axis); } @@ -367,26 +252,40 @@ void Q3DSurface::releaseAxis(Q3DValueAxis *axis) * * \sa addAxis() */ -QList<Q3DValueAxis *> Q3DSurface::axes() const +QList<QValue3DAxis *> Q3DSurface::axes() const { - QList<Q3DAbstractAxis *> abstractAxes = dptrc()->m_shared->axes(); - QList<Q3DValueAxis *> retList; - foreach (Q3DAbstractAxis *axis, abstractAxes) - retList.append(static_cast<Q3DValueAxis *>(axis)); + QList<QAbstract3DAxis *> abstractAxes = dptrc()->m_shared->axes(); + QList<QValue3DAxis *> retList; + foreach (QAbstract3DAxis *axis, abstractAxes) + retList.append(static_cast<QValue3DAxis *>(axis)); return retList; } -/////////////////// PRIVATE /////////////////////////////////// +// Q3DSurfacePrivate Q3DSurfacePrivate::Q3DSurfacePrivate(Q3DSurface *q) - : Q3DWindowPrivate(q) + : QAbstract3DGraphPrivate(q) { } Q3DSurfacePrivate::~Q3DSurfacePrivate() { - delete m_shared; +} + +void Q3DSurfacePrivate::handleAxisXChanged(QAbstract3DAxis *axis) +{ + emit qptr()->axisXChanged(static_cast<QValue3DAxis *>(axis)); +} + +void Q3DSurfacePrivate::handleAxisYChanged(QAbstract3DAxis *axis) +{ + emit qptr()->axisYChanged(static_cast<QValue3DAxis *>(axis)); +} + +void Q3DSurfacePrivate::handleAxisZChanged(QAbstract3DAxis *axis) +{ + emit qptr()->axisZChanged(static_cast<QValue3DAxis *>(axis)); } Q3DSurface *Q3DSurfacePrivate::qptr() @@ -394,4 +293,4 @@ Q3DSurface *Q3DSurfacePrivate::qptr() return static_cast<Q3DSurface *>(q_ptr); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h index bdbe65f5..7fb6e58a 100644 --- a/src/datavisualization/engine/q3dsurface.h +++ b/src/datavisualization/engine/q3dsurface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,68 +19,46 @@ #ifndef Q3DSURFACE_H #define Q3DSURFACE_H -#include <QtDataVisualization/qdatavisualizationenums.h> -#include <QtDataVisualization/q3dwindow.h> +#include <QtDataVisualization/qabstract3dgraph.h> #include <QtDataVisualization/q3dscene.h> #include <QFont> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DSurfacePrivate; -class Q3DValueAxis; +class QValue3DAxis; class QSurface3DSeries; -class Q3DTheme; -class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow +class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public QAbstract3DGraph { Q_OBJECT - Q_PROPERTY(QtDataVisualization::QDataVis::SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) - Q_PROPERTY(Q3DTheme* theme READ theme WRITE setTheme NOTIFY themeChanged) - Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) - Q_PROPERTY(Q3DScene* scene READ scene) + Q_PROPERTY(QValue3DAxis *axisX READ axisX WRITE setAxisX NOTIFY axisXChanged) + Q_PROPERTY(QValue3DAxis *axisY READ axisY WRITE setAxisY NOTIFY axisYChanged) + Q_PROPERTY(QValue3DAxis *axisZ READ axisZ WRITE setAxisZ NOTIFY axisZChanged) public: - explicit Q3DSurface(QWindow *parent = 0); + explicit Q3DSurface(const QSurfaceFormat *format = 0, QWindow *parent = 0); virtual ~Q3DSurface(); void addSeries(QSurface3DSeries *series); void removeSeries(QSurface3DSeries *series); - QList<QSurface3DSeries *> seriesList(); - - void setTheme(Q3DTheme *theme); - Q3DTheme *theme() const; - - void setShadowQuality(QDataVis::ShadowQuality quality); - QDataVis::ShadowQuality shadowQuality() const; - - void setSelectionMode(QDataVis::SelectionFlags mode); - QDataVis::SelectionFlags selectionMode() const; + QList<QSurface3DSeries *> seriesList() const; // Axes - void setAxisX(Q3DValueAxis *axis); - Q3DValueAxis *axisX() const; - void setAxisY(Q3DValueAxis *axis); - Q3DValueAxis *axisY() const; - void setAxisZ(Q3DValueAxis *axis); - Q3DValueAxis *axisZ() const; - void addAxis(Q3DValueAxis *axis); - void releaseAxis(Q3DValueAxis *axis); - QList<Q3DValueAxis *> axes() const; - - Q3DScene *scene() const; + void setAxisX(QValue3DAxis *axis); + QValue3DAxis *axisX() const; + void setAxisY(QValue3DAxis *axis); + QValue3DAxis *axisY() const; + void setAxisZ(QValue3DAxis *axis); + QValue3DAxis *axisZ() const; + void addAxis(QValue3DAxis *axis); + void releaseAxis(QValue3DAxis *axis); + QList<QValue3DAxis *> axes() const; signals: - void selectionModeChanged(QDataVis::SelectionFlags mode); - void themeChanged(Q3DTheme *theme); - void shadowQualityChanged(QDataVis::ShadowQuality quality); - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void touchEvent(QTouchEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); + void axisXChanged(QValue3DAxis *axis); + void axisYChanged(QValue3DAxis *axis); + void axisZChanged(QValue3DAxis *axis); private: Q3DSurfacePrivate *dptr(); @@ -88,6 +66,6 @@ private: Q_DISABLE_COPY(Q3DSurface) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DSURFACE_H +#endif diff --git a/src/datavisualization/engine/q3dsurface_p.h b/src/datavisualization/engine/q3dsurface_p.h index de2a518c..540956b6 100644 --- a/src/datavisualization/engine/q3dsurface_p.h +++ b/src/datavisualization/engine/q3dsurface_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -30,27 +30,30 @@ #define Q3DSURFACE_P_H #include "surface3dcontroller_p.h" -#include "qdatavisualizationenums.h" -#include "q3dwindow_p.h" +#include "qabstract3dgraph_p.h" #include <QList> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Q3DSurface; -class Q3DSurfacePrivate : public Q3DWindowPrivate +class Q3DSurfacePrivate : public QAbstract3DGraphPrivate { Q_OBJECT public: Q3DSurfacePrivate(Q3DSurface *q); ~Q3DSurfacePrivate(); + void handleAxisXChanged(QAbstract3DAxis *axis); + void handleAxisYChanged(QAbstract3DAxis *axis); + void handleAxisZChanged(QAbstract3DAxis *axis); + Q3DSurface *qptr(); Surface3DController *m_shared; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // Q3DSURFACE_P_H +#endif diff --git a/src/datavisualization/engine/q3dwindow.cpp b/src/datavisualization/engine/q3dwindow.cpp deleted file mode 100644 index 5285b585..00000000 --- a/src/datavisualization/engine/q3dwindow.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://qt.digia.com -** -** This file is part of the QtDataVisualization module. -** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. -** -** If you have questions regarding the use of this file, please use -** contact form at http://qt.digia.com -** -****************************************************************************/ - -#include "q3dwindow.h" -#include "q3dwindow_p.h" -#include "abstract3dcontroller_p.h" -#include "qabstract3dinputhandler_p.h" -#include "q3dscene_p.h" - -#include <QGuiApplication> -#include <QOpenGLContext> -#include <QOpenGLPaintDevice> -#include <QPainter> - - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE - -/*! - * \class Q3DWindow - * \inmodule QtDataVisualization - * \brief The Q3DWindow class provides a window and render loop. - * \since Qt Data Visualization 1.0 - * - * This class creates a QWindow and provides render loop for visualization types inheriting it. - * - * You should not need to use this class directly, but one of its subclasses instead. - * - * \note Q3DWindow sets window flag \c{Qt::FramelessWindowHint} on by default. If you want to display - * graph windows as standalone windows with regular window frame, clear this flag after constructing - * the graph. For example: - * - * \code - * Q3DBars *graphWindow = new Q3DBars; - * graphWindow->setFlags(graphWindow->flags() ^ Qt::FramelessWindowHint); - * \endcode - * - * \sa Q3DBars, Q3DScatter, Q3DSurface, {Qt Data Visualization C++ Classes} - */ - -/*! - * \internal - */ -Q3DWindow::Q3DWindow(Q3DWindowPrivate *d, QWindow *parent) - : QWindow(parent), - d_ptr(d) -{ - d_ptr->m_context = new QOpenGLContext(this); - - setFlags(flags() | Qt::FramelessWindowHint); - setSurfaceType(QWindow::OpenGLSurface); - QSurfaceFormat surfaceFormat; - surfaceFormat.setDepthBufferSize(24); -#if !defined(QT_OPENGL_ES_2) - surfaceFormat.setSamples(8); - surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL); -#else - surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); -#endif - surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - setFormat(surfaceFormat); - - create(); - - d_ptr->m_context->setFormat(requestedFormat()); - d_ptr->m_context->create(); - d_ptr->m_context->makeCurrent(this); - - initializeOpenGLFunctions(); - - const GLubyte *version = glGetString(GL_VERSION); - qDebug() << "OpenGL version:" << (const char *)version; - version = glGetString(GL_SHADING_LANGUAGE_VERSION); - qDebug() << "GLSL version:" << (const char *)version; -#if !defined(QT_OPENGL_ES_2) - // If we have real OpenGL, GLSL version must be 1.2 or over. Quit if not. - QStringList splitversionstr = QString::fromLatin1((const char *)version).split(QChar::fromLatin1(' ')); - if (splitversionstr[0].toFloat() < 1.2) - qFatal("GLSL version must be 1.20 or higher. Try installing latest display drivers."); -#endif - d_ptr->renderLater(); -} - -/*! - * Destroys Q3DWindow. - */ -Q3DWindow::~Q3DWindow() -{ -} - -/*! - * Adds the given \a inputHandler to the graph. The input handlers added via addInputHandler - * are not taken in to use directly. Only the ownership of the a\ inputHandler is given to the graph. - * The \a inputHandler must not be null or already added to another graph. - * - * \sa releaseInputHandler(), setActiveInputHandler() - */ -void Q3DWindow::addInputHandler(QAbstract3DInputHandler *inputHandler) -{ - d_ptr->m_visualController->addInputHandler(inputHandler); -} - -/*! - * Releases the ownership of the \a inputHandler back to the caller, if it was added to this graph. - * If the released \a inputHandler is in use there will be no input handler active after this call. - * - * If the default input handler is released and added back later, it behaves as any other input handler would. - * - * \sa addInputHandler(), setActiveInputHandler() - */ -void Q3DWindow::releaseInputHandler(QAbstract3DInputHandler *inputHandler) -{ - d_ptr->m_visualController->releaseInputHandler(inputHandler); -} - -/*! - * Sets the active \a inputHandler. Implicitly calls addInputHandler() to transfer ownership of - * the \a inputHandler to this graph. - * - * If the \a inputHandler is null, no input handler will be active after this call. - * - * \sa addInputHandler(), releaseInputHandler() - */ -void Q3DWindow::setActiveInputHandler(QAbstract3DInputHandler *inputHandler) -{ - d_ptr->m_visualController->setActiveInputHandler(inputHandler); -} - -/*! - * \return currently active input handler. - */ -QAbstract3DInputHandler *Q3DWindow::activeInputHandler() -{ - return d_ptr->m_visualController->activeInputHandler(); -} - -/*! - * \internal - */ -bool Q3DWindow::event(QEvent *event) -{ - switch (event->type()) { - case QEvent::UpdateRequest: - d_ptr->renderNow(); - return true; - case QEvent::TouchBegin: - case QEvent::TouchCancel: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - d_ptr->m_visualController->touchEvent(static_cast<QTouchEvent *>(event)); - return true; - default: - return QWindow::event(event); - } -} - -/*! - * \internal - */ -void Q3DWindow::resizeEvent(QResizeEvent *event) -{ - Q_UNUSED(event); - - Q3DScene *scene = d_ptr->m_visualController->scene(); - scene->d_ptr->setWindowSize(QSize(width(), height())); - scene->d_ptr->setViewport(QRect(0, 0, width(), height())); -} - -/*! - * \internal - */ -void Q3DWindow::exposeEvent(QExposeEvent *event) -{ - Q_UNUSED(event); - - if (isExposed()) - d_ptr->renderNow(); -} - -Q3DWindowPrivate::Q3DWindowPrivate(Q3DWindow *q) - : QObject(0), - q_ptr(q), - m_updatePending(false), - m_visualController(0), - m_devicePixelRatio(1.f) -{ -} - -Q3DWindowPrivate::~Q3DWindowPrivate() -{ -} - -void Q3DWindowPrivate::render() -{ - handleDevicePixelRatioChange(); - m_visualController->synchDataToRenderer(); - m_visualController->render(); -} - -void Q3DWindowPrivate::renderLater() -{ - if (!m_updatePending) { - m_updatePending = true; - QCoreApplication::postEvent(q_ptr, new QEvent(QEvent::UpdateRequest)); - } -} - -void Q3DWindowPrivate::renderNow() -{ - if (!q_ptr->isExposed()) - return; - - m_updatePending = false; - - m_context->makeCurrent(q_ptr); - - render(); - - m_context->swapBuffers(q_ptr); -} - -void Q3DWindowPrivate::setVisualController(Abstract3DController *controller) -{ - m_visualController = controller; -} - -void Q3DWindowPrivate::handleDevicePixelRatioChange() -{ - if (q_ptr->devicePixelRatio() == m_devicePixelRatio || !m_visualController) - return; - - m_devicePixelRatio = q_ptr->devicePixelRatio(); - m_visualController->scene()->setDevicePixelRatio(m_devicePixelRatio); -} - -QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dwindow.h b/src/datavisualization/engine/q3dwindow.h deleted file mode 100644 index cdffc6b9..00000000 --- a/src/datavisualization/engine/q3dwindow.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://qt.digia.com -** -** This file is part of the QtDataVisualization module. -** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. -** -** If you have questions regarding the use of this file, please use -** contact form at http://qt.digia.com -** -****************************************************************************/ - -#ifndef Q3DWINDOW_H -#define Q3DWINDOW_H - -#include <QtDataVisualization/qdatavisualizationenums.h> - -#include <QWindow> -#include <QOpenGLFunctions> -#include <QScreen> - -class QPainter; - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE - -class Q3DWindowPrivate; -class Abstract3DController; -class QAbstract3DInputHandler; - -class QT_DATAVISUALIZATION_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions -{ - Q_OBJECT - -protected: - explicit Q3DWindow(Q3DWindowPrivate *d, QWindow *parent = 0); -public: - virtual ~Q3DWindow(); - - void addInputHandler(QAbstract3DInputHandler *inputHandler); - void releaseInputHandler(QAbstract3DInputHandler *inputHandler); - void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); - QAbstract3DInputHandler *activeInputHandler(); - -protected: - bool event(QEvent *event); - void resizeEvent(QResizeEvent *event); - void exposeEvent(QExposeEvent *event); - -private: - QScopedPointer<Q3DWindowPrivate> d_ptr; - - friend class Q3DBars; - friend class Q3DScatter; - friend class Q3DSurface; -}; - -QT_DATAVISUALIZATION_END_NAMESPACE - -#endif diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp new file mode 100644 index 00000000..d8146149 --- /dev/null +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -0,0 +1,512 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qabstract3dgraph.h" +#include "qabstract3dgraph_p.h" +#include "abstract3dcontroller_p.h" +#include "qabstract3dinputhandler_p.h" +#include "q3dscene_p.h" +#include "qutils.h" + +#include <QGuiApplication> +#include <QOpenGLContext> +#include <QOpenGLPaintDevice> +#include <QPainter> + + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +/*! + * \class QAbstract3DGraph + * \inmodule QtDataVisualization + * \brief The QAbstract3DGraph class provides a window and render loop for graphs. + * \since Qt Data Visualization 1.0 + * + * This class subclasses a QWindow and provides render loop for graphs inheriting it. + * + * You should not need to use this class directly, but one of its subclasses instead. + * + * Anti-aliasing is turned on by default on C++, except in OpenGL ES2 + * environments, where anti-aliasing is not supported by Qt Data Visualization. + * To specify non-default anti-aliasing for a graph, give a custom surface format as + * a constructor parameter. You can use the convenience function \c QtDataVisualization::qDefaultSurfaceFormat() + * to create the surface format object. + * + * \note QAbstract3DGraph sets window flag \c Qt::FramelessWindowHint on by default. If you want to display + * graph windows as standalone windows with regular window frame, clear this flag after constructing + * the graph. For example: + * + * \code + * Q3DBars *graphWindow = new Q3DBars; + * graphWindow->setFlags(graphWindow->flags() ^ Qt::FramelessWindowHint); + * \endcode + * + * \sa Q3DBars, Q3DScatter, Q3DSurface, {Qt Data Visualization C++ Classes} + */ + +/*! + \enum QAbstract3DGraph::SelectionFlag + + Item selection modes. Values of this enumeration can be combined with OR operator. + + \value SelectionNone + Selection mode disabled. + \value SelectionItem + Selection highlights a single item. + \value SelectionRow + Selection highlights a single row. + \value SelectionItemAndRow + Combination flag for highlighting both item and row with different colors. + \value SelectionColumn + Selection highlights a single column. + \value SelectionItemAndColumn + Combination flag for highlighting both item and column with different colors. + \value SelectionRowAndColumn + Combination flag for highlighting both row and column. + \value SelectionItemRowAndColumn + Combination flag for highlighting item, row, and column. + \value SelectionSlice + Setting this mode flag indicates that the graph should take care of the slice view handling + automatically. If you wish to control the slice view yourself via Q3DScene, do not set this + flag. When setting this mode flag, either \c SelectionRow or \c SelectionColumn must also + be set, but not both. Slicing is supported by Q3DBars and Q3DSurface only. + \value SelectionMultiSeries + Setting this mode means that items for all series at same position are highlighted, instead + of just the selected item. The actual selection in the other series doesn't change. + Multi-series selection is only supported for Q3DBars. +*/ + +/*! + \enum QAbstract3DGraph::ShadowQuality + + Quality of shadows. + + \value ShadowQualityNone + Shadows are disabled. + \value ShadowQualityLow + Shadows are rendered in low quality. + \value ShadowQualityMedium + Shadows are rendered in medium quality. + \value ShadowQualityHigh + Shadows are rendered in high quality. + \value ShadowQualitySoftLow + Shadows are rendered in low quality with softened edges. + \value ShadowQualitySoftMedium + Shadows are rendered in medium quality with softened edges. + \value ShadowQualitySoftHigh + Shadows are rendered in high quality with softened edges. +*/ + +/*! + * \internal + */ +QAbstract3DGraph::QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format, + QWindow *parent) + : QWindow(parent), + d_ptr(d) +{ + qRegisterMetaType<QAbstract3DGraph::ShadowQuality>("QAbstract3DGraph::ShadowQuality"); + + // Default to frameless window, as typically graphs are not toplevel + setFlags(flags() | Qt::FramelessWindowHint); + + QSurfaceFormat surfaceFormat; + if (format) { + surfaceFormat = *format; + // Make sure renderable type is correct +#if !defined(QT_OPENGL_ES_2) + surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL); +#else + surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES); +#endif + } else { + surfaceFormat = qDefaultSurfaceFormat(); + } + + d_ptr->m_context = new QOpenGLContext(this); + setSurfaceType(QWindow::OpenGLSurface); + setFormat(surfaceFormat); + + create(); + + d_ptr->m_context->setFormat(requestedFormat()); + d_ptr->m_context->create(); + d_ptr->m_context->makeCurrent(this); + + initializeOpenGLFunctions(); + + const GLubyte *shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); +#ifndef QT_NO_DEBUG + const GLubyte *openGLVersion = glGetString(GL_VERSION); + qDebug() << "OpenGL version:" << (const char *)openGLVersion; + qDebug() << "GLSL version:" << (const char *)shaderVersion; +#endif + +#if !defined(QT_OPENGL_ES_2) + // If we have real OpenGL, GLSL version must be 1.2 or over. Quit if not. + QStringList splitversionstr = QString::fromLatin1((const char *)shaderVersion).split(QChar::fromLatin1(' ')); + if (splitversionstr[0].toFloat() < 1.2) + qFatal("GLSL version must be 1.20 or higher. Try installing latest display drivers."); +#else + Q_UNUSED(shaderVersion) +#endif + + d_ptr->renderLater(); +} + +/*! + * Destroys QAbstract3DGraph. + */ +QAbstract3DGraph::~QAbstract3DGraph() +{ +} + +/*! + * Adds the given \a inputHandler to the graph. The input handlers added via addInputHandler + * are not taken in to use directly. Only the ownership of the \a inputHandler is given to the graph. + * The \a inputHandler must not be null or already added to another graph. + * + * \sa releaseInputHandler(), setActiveInputHandler() + */ +void QAbstract3DGraph::addInputHandler(QAbstract3DInputHandler *inputHandler) +{ + d_ptr->m_visualController->addInputHandler(inputHandler); +} + +/*! + * Releases the ownership of the \a inputHandler back to the caller, if it was added to this graph. + * If the released \a inputHandler is in use there will be no input handler active after this call. + * + * If the default input handler is released and added back later, it behaves as any other input handler would. + * + * \sa addInputHandler(), setActiveInputHandler() + */ +void QAbstract3DGraph::releaseInputHandler(QAbstract3DInputHandler *inputHandler) +{ + d_ptr->m_visualController->releaseInputHandler(inputHandler); +} + +/*! + * \property QAbstract3DGraph::activeInputHandler + * + * The active \a inputHandler used in the graph. Implicitly calls addInputHandler() to transfer + * ownership of the \a inputHandler to this graph. + * + * If the \a inputHandler is null, no input handler will be active after this call. + * + * \sa addInputHandler(), releaseInputHandler() + */ +void QAbstract3DGraph::setActiveInputHandler(QAbstract3DInputHandler *inputHandler) +{ + d_ptr->m_visualController->setActiveInputHandler(inputHandler); +} + +QAbstract3DInputHandler *QAbstract3DGraph::activeInputHandler() +{ + return d_ptr->m_visualController->activeInputHandler(); +} + +/*! + * \return list of all added input handlers. + * + * \sa addInputHandler() + */ +QList<QAbstract3DInputHandler *> QAbstract3DGraph::inputHandlers() const +{ + return d_ptr->m_visualController->inputHandlers(); +} + +/*! + * Adds the given \a theme to the graph. The themes added via addTheme are not taken in to use + * directly. Only the ownership of the a\ theme is given to the graph. + * The \a theme must not be null or already added to another graph. + * + * \sa releaseTheme(), setActiveTheme() + */ +void QAbstract3DGraph::addTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->addTheme(theme); +} + +/*! + * Releases the ownership of the \a theme back to the caller, if it was added to this graph. + * If the released \a theme is in use, a new default theme will be created and set active. + * + * If the default theme is released and added back later, it behaves as any other theme would. + * + * \sa addTheme(), setActiveTheme() + */ +void QAbstract3DGraph::releaseTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->releaseTheme(theme); +} + +/*! + * \property QAbstract3DGraph::activeTheme + * + * The active \a theme to be used for the graph. Implicitly calls addTheme() to transfer ownership + * of the \a theme to this graph. + * If the \a theme is null, a temporary default theme is created. This temporary theme is destroyed + * if any theme is explicitly set later. + * Properties of the \a theme can be modified even after setting it, and the modifications take + * effect immediately. + */ +void QAbstract3DGraph::setActiveTheme(Q3DTheme *theme) +{ + d_ptr->m_visualController->setActiveTheme(theme); +} + + +Q3DTheme *QAbstract3DGraph::activeTheme() const +{ + return d_ptr->m_visualController->activeTheme(); +} + +/*! + * \return list of all added themes. + * + * \sa addTheme() + */ +QList<Q3DTheme *> QAbstract3DGraph::themes() const +{ + return d_ptr->m_visualController->themes(); +} + +/*! + * \property QAbstract3DGraph::selectionMode + * + * Sets selection \a mode to a combination of SelectionFlags. It is preset to + * \c SelectionItem by default. + * Different graph types support different selection modes. See SelectionFlags + * documentation for details. + */ +void QAbstract3DGraph::setSelectionMode(SelectionFlags mode) +{ + d_ptr->m_visualController->setSelectionMode(mode); +} + +QAbstract3DGraph::SelectionFlags QAbstract3DGraph::selectionMode() const +{ + return d_ptr->m_visualController->selectionMode(); +} + +/*! + * \property QAbstract3DGraph::shadowQuality + * + * Sets shadow \a quality to one of ShadowQuality. It is preset to + * \c ShadowQualityMedium by default. + * + * \note If setting ShadowQuality of a certain level fails, a level is lowered + * until it is successful and shadowQualityChanged signal is emitted for each time the change is + * done. + */ +void QAbstract3DGraph::setShadowQuality(ShadowQuality quality) +{ + d_ptr->m_visualController->setShadowQuality(quality); +} + +QAbstract3DGraph::ShadowQuality QAbstract3DGraph::shadowQuality() const +{ + return d_ptr->m_visualController->shadowQuality(); +} + +/*! + * \property QAbstract3DGraph::scene + * + * This property contains the read only Q3DScene that can be used to access for example a camera object. + */ +Q3DScene *QAbstract3DGraph::scene() const +{ + return d_ptr->m_visualController->scene(); +} + +/*! + * Clears selection from all attached series. + */ +void QAbstract3DGraph::clearSelection() +{ + d_ptr->m_visualController->clearSelection(); +} + +/*! + * \internal + */ +bool QAbstract3DGraph::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::UpdateRequest: + d_ptr->renderNow(); + return true; + case QEvent::TouchBegin: + case QEvent::TouchCancel: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + d_ptr->m_visualController->touchEvent(static_cast<QTouchEvent *>(event)); + return true; + default: + return QWindow::event(event); + } +} + +/*! + * \internal + */ +void QAbstract3DGraph::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event); + + Q3DScene *scene = d_ptr->m_visualController->scene(); + scene->d_ptr->setWindowSize(QSize(width(), height())); + scene->d_ptr->setViewport(QRect(0, 0, width(), height())); +} + +/*! + * \internal + */ +void QAbstract3DGraph::exposeEvent(QExposeEvent *event) +{ + Q_UNUSED(event); + + if (isExposed()) + d_ptr->renderNow(); +} + +/*! + * \internal + */ +void QAbstract3DGraph::mouseDoubleClickEvent(QMouseEvent *event) +{ + d_ptr->m_visualController->mouseDoubleClickEvent(event); +} + +/*! + * \internal + */ +void QAbstract3DGraph::touchEvent(QTouchEvent *event) +{ + d_ptr->m_visualController->touchEvent(event); +} + +/*! + * \internal + */ +void QAbstract3DGraph::mousePressEvent(QMouseEvent *event) +{ + d_ptr->m_visualController->mousePressEvent(event, event->pos()); +} + +/*! + * \internal + */ +void QAbstract3DGraph::mouseReleaseEvent(QMouseEvent *event) +{ + d_ptr->m_visualController->mouseReleaseEvent(event, event->pos()); +} + +/*! + * \internal + */ +void QAbstract3DGraph::mouseMoveEvent(QMouseEvent *event) +{ + d_ptr->m_visualController->mouseMoveEvent(event, event->pos()); +} + +/*! + * \internal + */ +void QAbstract3DGraph::wheelEvent(QWheelEvent *event) +{ + d_ptr->m_visualController->wheelEvent(event); +} + +QAbstract3DGraphPrivate::QAbstract3DGraphPrivate(QAbstract3DGraph *q) + : QObject(0), + q_ptr(q), + m_updatePending(false), + m_visualController(0), + m_devicePixelRatio(1.f) +{ +} + +QAbstract3DGraphPrivate::~QAbstract3DGraphPrivate() +{ + delete m_visualController; +} + +void QAbstract3DGraphPrivate::setVisualController(Abstract3DController *controller) +{ + m_visualController = controller; + + QObject::connect(m_visualController, &Abstract3DController::activeInputHandlerChanged, q_ptr, + &QAbstract3DGraph::activeInputHandlerChanged); + QObject::connect(m_visualController, &Abstract3DController::activeThemeChanged, q_ptr, + &QAbstract3DGraph::activeThemeChanged); + QObject::connect(m_visualController, &Abstract3DController::selectionModeChanged, q_ptr, + &QAbstract3DGraph::selectionModeChanged); + QObject::connect(m_visualController, &Abstract3DController::shadowQualityChanged, q_ptr, + &QAbstract3DGraph::shadowQualityChanged); + QObject::connect(m_visualController, &Abstract3DController::needRender, this, + &QAbstract3DGraphPrivate::renderLater); + + QObject::connect(m_visualController, &Abstract3DController::axisXChanged, this, + &QAbstract3DGraphPrivate::handleAxisXChanged); + QObject::connect(m_visualController, &Abstract3DController::axisYChanged, this, + &QAbstract3DGraphPrivate::handleAxisYChanged); + QObject::connect(m_visualController, &Abstract3DController::axisZChanged, this, + &QAbstract3DGraphPrivate::handleAxisZChanged); +} + +void QAbstract3DGraphPrivate::handleDevicePixelRatioChange() +{ + if (q_ptr->devicePixelRatio() == m_devicePixelRatio || !m_visualController) + return; + + m_devicePixelRatio = q_ptr->devicePixelRatio(); + m_visualController->scene()->setDevicePixelRatio(m_devicePixelRatio); +} + +void QAbstract3DGraphPrivate::render() +{ + handleDevicePixelRatioChange(); + m_visualController->synchDataToRenderer(); + m_visualController->render(); +} + +void QAbstract3DGraphPrivate::renderLater() +{ + if (!m_updatePending) { + m_updatePending = true; + QCoreApplication::postEvent(q_ptr, new QEvent(QEvent::UpdateRequest)); + } +} + +void QAbstract3DGraphPrivate::renderNow() +{ + if (!q_ptr->isExposed()) + return; + + m_updatePending = false; + + m_context->makeCurrent(q_ptr); + + render(); + + m_context->swapBuffers(q_ptr); +} + +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h new file mode 100644 index 00000000..9534ce5c --- /dev/null +++ b/src/datavisualization/engine/qabstract3dgraph.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QABSTRACT3DGRAPH_H +#define QABSTRACT3DGRAPH_H + +#include <QtDataVisualization/qdatavisualizationglobal.h> + +#include <QWindow> +#include <QOpenGLFunctions> +#include <QScreen> + +QT_BEGIN_NAMESPACE_DATAVISUALIZATION + +class QAbstract3DGraphPrivate; +class Abstract3DController; +class QAbstract3DInputHandler; +class Q3DTheme; +class Q3DScene; + +class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected QOpenGLFunctions +{ + Q_OBJECT + Q_ENUMS(ShadowQuality) + Q_FLAGS(SelectionFlag SelectionFlags) + Q_PROPERTY(QAbstract3DInputHandler* activeInputHandler READ activeInputHandler WRITE setActiveInputHandler NOTIFY activeInputHandlerChanged) + Q_PROPERTY(Q3DTheme* activeTheme READ activeTheme WRITE setActiveTheme NOTIFY activeThemeChanged) + Q_PROPERTY(SelectionFlags selectionMode READ selectionMode WRITE setSelectionMode NOTIFY selectionModeChanged) + Q_PROPERTY(ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged) + Q_PROPERTY(Q3DScene* scene READ scene) + +protected: + explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format, QWindow *parent = 0); + +public: + enum SelectionFlag { + SelectionNone = 0, + SelectionItem = 1, + SelectionRow = 2, + SelectionItemAndRow = SelectionItem | SelectionRow, + SelectionColumn = 4, + SelectionItemAndColumn = SelectionItem | SelectionColumn, + SelectionRowAndColumn = SelectionRow | SelectionColumn, + SelectionItemRowAndColumn = SelectionItem | SelectionRow | SelectionColumn, + SelectionSlice = 8, + SelectionMultiSeries = 16 + }; + Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag) + + enum ShadowQuality { + ShadowQualityNone = 0, + ShadowQualityLow, + ShadowQualityMedium, + ShadowQualityHigh, + ShadowQualitySoftLow, + ShadowQualitySoftMedium, + ShadowQualitySoftHigh + }; + +public: + virtual ~QAbstract3DGraph(); + + void addInputHandler(QAbstract3DInputHandler *inputHandler); + void releaseInputHandler(QAbstract3DInputHandler *inputHandler); + void setActiveInputHandler(QAbstract3DInputHandler *inputHandler); + QAbstract3DInputHandler *activeInputHandler(); + QList<QAbstract3DInputHandler *> inputHandlers() const; + + void addTheme(Q3DTheme *theme); + void releaseTheme(Q3DTheme *theme); + void setActiveTheme(Q3DTheme *theme); + Q3DTheme *activeTheme() const; + QList<Q3DTheme *> themes() const; + + void setSelectionMode(SelectionFlags mode); + SelectionFlags selectionMode() const; + + void setShadowQuality(ShadowQuality quality); + ShadowQuality shadowQuality() const; + + Q3DScene *scene() const; + + void clearSelection(); + +protected: + bool event(QEvent *event); + void resizeEvent(QResizeEvent *event); + void exposeEvent(QExposeEvent *event); + + void mouseDoubleClickEvent(QMouseEvent *event); + void touchEvent(QTouchEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + +signals: + void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); + void activeThemeChanged(Q3DTheme *theme); + void selectionModeChanged(SelectionFlags mode); + void shadowQualityChanged(ShadowQuality quality); + +private: + QScopedPointer<QAbstract3DGraphPrivate> d_ptr; + + friend class Q3DBars; + friend class Q3DScatter; + friend class Q3DSurface; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstract3DGraph::SelectionFlags) + +QT_END_NAMESPACE_DATAVISUALIZATION + +#endif diff --git a/src/datavisualization/engine/q3dwindow_p.h b/src/datavisualization/engine/qabstract3dgraph_p.h index ba8c67da..a353797b 100644 --- a/src/datavisualization/engine/q3dwindow_p.h +++ b/src/datavisualization/engine/qabstract3dgraph_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -26,8 +26,8 @@ // // We mean it. -#ifndef Q3DWINDOW_P_H -#define Q3DWINDOW_P_H +#ifndef QABSTRACT3DGRAPH_P_H +#define QABSTRACT3DGRAPH_P_H #include "datavisualizationglobal_p.h" @@ -36,29 +36,34 @@ class QOpenGLContext; class QOpenGLPaintDevice; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -class Q3DWindow; +class QAbstract3DGraph; class Abstract3DController; +class QAbstract3DAxis; -class Q3DWindowPrivate : public QObject +class QAbstract3DGraphPrivate : public QObject { Q_OBJECT public: - Q3DWindowPrivate(Q3DWindow *q); - ~Q3DWindowPrivate(); - - void render(); + QAbstract3DGraphPrivate(QAbstract3DGraph *q); + ~QAbstract3DGraphPrivate(); void setVisualController(Abstract3DController *controller); void handleDevicePixelRatioChange(); + void render(); + public slots: void renderLater(); void renderNow(); + virtual void handleAxisXChanged(QAbstract3DAxis *axis) = 0; + virtual void handleAxisYChanged(QAbstract3DAxis *axis) = 0; + virtual void handleAxisZChanged(QAbstract3DAxis *axis) = 0; + public: - Q3DWindow *q_ptr; + QAbstract3DGraph *q_ptr; bool m_updatePending; QOpenGLContext *m_context; @@ -66,6 +71,6 @@ public: float m_devicePixelRatio; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp index 0a506f19..a1850a3c 100644 --- a/src/datavisualization/engine/scatter3dcontroller.cpp +++ b/src/datavisualization/engine/scatter3dcontroller.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,21 +19,24 @@ #include "scatter3dcontroller_p.h" #include "scatter3drenderer_p.h" #include "camerahelper_p.h" -#include "q3dabstractaxis_p.h" -#include "q3dvalueaxis_p.h" +#include "qabstract3daxis_p.h" +#include "qvalue3daxis_p.h" #include "qscatterdataproxy_p.h" #include "qscatter3dseries_p.h" #include <QMatrix4x4> #include <qmath.h> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -Scatter3DController::Scatter3DController(QRect boundRect) - : Abstract3DController(boundRect), +static const int insertRemoveRecordReserveSize = 31; + +Scatter3DController::Scatter3DController(QRect boundRect, Q3DScene *scene) + : Abstract3DController(boundRect, scene), m_renderer(0), m_selectedItem(invalidSelectionIndex()), - m_selectedItemSeries(0) + m_selectedItemSeries(0), + m_recordInsertsAndRemoves(false) { // Setting a null axis creates a new default axis according to orientation and graph type. // Note: These cannot be set in Abstract3DController constructor, as they will call virtual @@ -57,18 +60,16 @@ void Scatter3DController::initializeOpenGL() setRenderer(m_renderer); synchDataToRenderer(); - QObject::connect(m_renderer, &Scatter3DRenderer::itemClicked, this, - &Scatter3DController::handleItemClicked, Qt::QueuedConnection); emitNeedRender(); } void Scatter3DController::synchDataToRenderer() { - Abstract3DController::synchDataToRenderer(); - if (!isInitialized()) return; + Abstract3DController::synchDataToRenderer(); + // Notify changes to renderer if (m_changeTracker.selectedItemChanged) { m_renderer->updateSelectedItem(m_selectedItem, m_selectedItemSeries); @@ -80,11 +81,9 @@ void Scatter3DController::addSeries(QAbstract3DSeries *series) { Q_ASSERT(series && series->type() == QAbstract3DSeries::SeriesTypeScatter); - bool firstAdded = !m_seriesList.size(); - Abstract3DController::addSeries(series); - if (firstAdded) + if (series->isVisible()) adjustValueAxisRange(); QScatter3DSeries *scatterSeries = static_cast<QScatter3DSeries *>(series); @@ -94,14 +93,14 @@ void Scatter3DController::addSeries(QAbstract3DSeries *series) void Scatter3DController::removeSeries(QAbstract3DSeries *series) { - bool firstRemoved = (m_seriesList.size() && m_seriesList.at(0) == series); + bool wasVisible = (series && series->d_ptr->m_controller == this && series->isVisible()); Abstract3DController::removeSeries(series); if (m_selectedItemSeries == series) setSelectedItem(invalidSelectionIndex(), 0); - if (firstRemoved) + if (wasVisible) adjustValueAxisRange(); } @@ -120,8 +119,11 @@ QList<QScatter3DSeries *> Scatter3DController::scatterSeriesList() void Scatter3DController::handleArrayReset() { - adjustValueAxisRange(); - m_isDataDirty = true; + QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } setSelectedItem(m_selectedItem, m_selectedItemSeries); emitNeedRender(); } @@ -130,9 +132,11 @@ void Scatter3DController::handleItemsAdded(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO should dirty only affected values? - adjustValueAxisRange(); - m_isDataDirty = true; + QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -140,9 +144,11 @@ void Scatter3DController::handleItemsChanged(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO should dirty only affected values? - adjustValueAxisRange(); - m_isDataDirty = true; + QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -150,12 +156,29 @@ void Scatter3DController::handleItemsRemoved(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO should dirty only affected values? - adjustValueAxisRange(); - m_isDataDirty = true; + QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); + if (series == m_selectedItemSeries) { + // If items removed from selected series before the selection, adjust the selection + int selectedItem = m_selectedItem; + if (startIndex <= selectedItem) { + if ((startIndex + count) > selectedItem) + selectedItem = -1; // Selected item removed + else + selectedItem -= count; // Move selected item down by amount of item removed + + setSelectedItem(selectedItem, m_selectedItemSeries); + } + } - // Clear selection unless it is still valid - setSelectedItem(m_selectedItem, m_selectedItemSeries); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } + + if (m_recordInsertsAndRemoves) { + InsertRemoveRecord record(false, startIndex, count, series); + m_insertRemoveRecords.append(record); + } emitNeedRender(); } @@ -164,22 +187,45 @@ void Scatter3DController::handleItemsInserted(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO should dirty only affected values? - adjustValueAxisRange(); - m_isDataDirty = true; + QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); + if (series == m_selectedItemSeries) { + // If items inserted to selected series before the selection, adjust the selection + int selectedItem = m_selectedItem; + if (startIndex <= selectedItem) { + selectedItem += count; + setSelectedItem(selectedItem, m_selectedItemSeries); + } + } + + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } + + if (m_recordInsertsAndRemoves) { + InsertRemoveRecord record(true, startIndex, count, series); + m_insertRemoveRecords.append(record); + } + emitNeedRender(); } -void Scatter3DController::handleItemClicked(int index, QScatter3DSeries *series) +void Scatter3DController::startRecordingRemovesAndInserts() { - setSelectedItem(index, series); - - // TODO: pass clicked to parent. (QTRD-2517) - // TODO: Also hover needed? (QTRD-2131) + m_recordInsertsAndRemoves = false; + + if (m_scene->selectionQueryPosition() != Q3DScene::invalidSelectionPoint()) { + m_recordInsertsAndRemoves = true; + if (m_insertRemoveRecords.size()) { + m_insertRemoveRecords.clear(); + // Reserve some space for remove/insert records to avoid unnecessary reallocations. + m_insertRemoveRecords.reserve(insertRemoveRecordReserveSize); + } + } } void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation( - Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) { Q_UNUSED(orientation) Q_UNUSED(autoAdjust) @@ -194,10 +240,47 @@ void Scatter3DController::handleAxisRangeChangedBySender(QObject *sender) setSelectedItem(m_selectedItem, m_selectedItemSeries); } -void Scatter3DController::setSelectionMode(QDataVis::SelectionFlags mode) +void Scatter3DController::handleSeriesVisibilityChangedBySender(QObject *sender) +{ + Abstract3DController::handleSeriesVisibilityChangedBySender(sender); + + adjustValueAxisRange(); +} + +void Scatter3DController::handlePendingClick() +{ + int index = m_renderer->clickedIndex(); + QScatter3DSeries *series = static_cast<QScatter3DSeries *>(m_renderer->clickedSeries()); + + // Adjust position according to recorded events + int recordCount = m_insertRemoveRecords.size(); + if (recordCount) { + for (int i = 0; i < recordCount; i++) { + const InsertRemoveRecord &record = m_insertRemoveRecords.at(i); + if (series == record.m_series && record.m_startIndex <= index) { + if (record.m_isInsert) { + index += record.m_count; + } else { + if ((record.m_startIndex + record.m_count) > index) { + index = -1; // Selected row removed + break; + } else { + index -= record.m_count; // Move selected item down by amount of items removed + } + } + } + } + } + + setSelectedItem(index, series); + + m_renderer->resetClickedStatus(); +} + +void Scatter3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { // We only support single item selection mode and no selection mode - if (mode != QDataVis::SelectionItem && mode != QDataVis::SelectionNone) { + if (mode != QAbstract3DGraph::SelectionItem && mode != QAbstract3DGraph::SelectionNone) { qWarning("Unsupported selection mode - only none and item selection modes are supported."); return; } @@ -237,11 +320,16 @@ void Scatter3DController::setSelectedItem(int index, QScatter3DSeries *series) } } +void Scatter3DController::clearSelection() +{ + setSelectedItem(invalidSelectionIndex(), 0); +} + void Scatter3DController::adjustValueAxisRange() { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); + QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX); + QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY); + QValue3DAxis *valueAxisZ = static_cast<QValue3DAxis *>(m_axisZ); bool adjustX = (valueAxisX && valueAxisX->isAutoAdjustRange()); bool adjustY = (valueAxisY && valueAxisY->isAutoAdjustRange()); bool adjustZ = (valueAxisZ && valueAxisZ->isAutoAdjustRange()); @@ -347,4 +435,4 @@ void Scatter3DController::adjustValueAxisRange() } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h index 00c87d4f..173d4e05 100644 --- a/src/datavisualization/engine/scatter3dcontroller_p.h +++ b/src/datavisualization/engine/scatter3dcontroller_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,9 +32,7 @@ #include "datavisualizationglobal_p.h" #include "abstract3dcontroller_p.h" -//#define DISPLAY_RENDER_SPEED - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Scatter3DRenderer; class QScatterDataProxy; @@ -62,17 +60,42 @@ private: QScatter3DSeries *m_selectedItemSeries; // Points to the series for which the bar is selected // in single series selection cases. + struct InsertRemoveRecord { + bool m_isInsert; + int m_startIndex; + int m_count; + QAbstract3DSeries *m_series; + + InsertRemoveRecord() : + m_isInsert(false), + m_startIndex(0), + m_count(0), + m_series(0) + {} + + InsertRemoveRecord(bool isInsert, int startIndex, int count, QAbstract3DSeries *series) : + m_isInsert(isInsert), + m_startIndex(startIndex), + m_count(count), + m_series(series) + {} + }; + + QVector<InsertRemoveRecord> m_insertRemoveRecords; + bool m_recordInsertsAndRemoves; + public: - explicit Scatter3DController(QRect rect); + explicit Scatter3DController(QRect rect, Q3DScene *scene = 0); ~Scatter3DController(); virtual void initializeOpenGL(); // Change selection mode - void setSelectionMode(QDataVis::SelectionFlags mode); + void setSelectionMode(QAbstract3DGraph::SelectionFlags mode); void setSelectedItem(int index, QScatter3DSeries *series); static inline int invalidSelectionIndex() { return -1; } + virtual void clearSelection(); void synchDataToRenderer(); @@ -80,8 +103,11 @@ public: virtual void removeSeries(QAbstract3DSeries *series); virtual QList<QScatter3DSeries *> scatterSeriesList(); - virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); + virtual void handleAxisAutoAdjustRangeChangedInOrientation( + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust); virtual void handleAxisRangeChangedBySender(QObject *sender); + virtual void handleSeriesVisibilityChangedBySender(QObject *sender); + virtual void handlePendingClick(); public slots: void handleArrayReset(); @@ -90,8 +116,8 @@ public slots: void handleItemsRemoved(int startIndex, int count); void handleItemsInserted(int startIndex, int count); - // Renderer callback handlers - void handleItemClicked(int index, QScatter3DSeries *series); +protected: + virtual void startRecordingRemovesAndInserts(); private: void adjustValueAxisRange(); @@ -99,7 +125,6 @@ private: Q_DISABLE_COPY(Scatter3DController) }; - -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index ee5c119e..cf9dbefe 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -41,7 +41,7 @@ // You should see the scene from where the light is //#define SHOW_DEPTH_TEXTURE_SCENE -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION //#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values @@ -90,7 +90,8 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_dotSizeScale(1.0f), m_hasHeightAdjustmentChanged(true), m_backgroundMargin(defaultMargin), - m_maxItemSize(0.0f) + m_maxItemSize(0.0f), + m_clickedIndex(Scatter3DController::invalidSelectionIndex()) { initializeOpenGLFunctions(); initializeOpenGL(); @@ -160,10 +161,15 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis float maxItemSize = 0.0f; float itemSize = 0.0f; + if (m_cachedItemSize.size() != seriesCount) + m_cachedItemSize.resize(seriesCount); + for (int series = 0; series < seriesCount; series++) { itemSize = static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize(); if (maxItemSize < itemSize) maxItemSize = itemSize; + if (m_cachedItemSize.at(series) != itemSize) + m_cachedItemSize[series] = itemSize; } m_backgroundMargin = defaultMargin; m_maxItemSize = maxItemSize; @@ -198,14 +204,16 @@ void Scatter3DRenderer::updateData() for (int i = 0; i < dataSize; i++) { QVector3D dotPos = dataArray.at(i).position(); + ScatterRenderItem &renderItem = m_renderingArrays[series][i]; if ((dotPos.x() >= minX && dotPos.x() <= maxX ) && (dotPos.y() >= minY && dotPos.y() <= maxY) && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) { - m_renderingArrays[series][i].setPosition(dotPos); - m_renderingArrays[series][i].setVisible(true); - calculateTranslation(m_renderingArrays[series][i]); + renderItem.setPosition(dotPos); + renderItem.setVisible(true); + renderItem.setRotation(dataArray.at(i).rotation()); + calculateTranslation(renderItem); } else { - m_renderingArrays[series][i].setVisible(false); + renderItem.setVisible(false); } } } @@ -217,11 +225,10 @@ void Scatter3DRenderer::updateData() void Scatter3DRenderer::updateScene(Q3DScene *scene) { - // TODO: See QTRD-2374 scene->activeCamera()->setMinYRotation(-90.0f); if (m_hasHeightAdjustmentChanged) { - // Set initial m_cachedScene->activeCamera() position. Also update if height adjustment has changed. + // Set initial camera position. Also update if height adjustment has changed. scene->activeCamera()->setBaseOrientation(cameraDistanceVector, zeroVector, upVector); m_hasHeightAdjustmentChanged = false; } @@ -229,6 +236,12 @@ void Scatter3DRenderer::updateScene(Q3DScene *scene) Abstract3DRenderer::updateScene(scene); } +void Scatter3DRenderer::resetClickedStatus() +{ + m_clickedIndex = Scatter3DController::invalidSelectionIndex(); + m_clickedSeries = 0; +} + void Scatter3DRenderer::render(GLuint defaultFboHandle) { // Handle GL state setup for FBO buffers and clearing of the render surface @@ -241,9 +254,12 @@ void Scatter3DRenderer::render(GLuint defaultFboHandle) void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) { GLfloat backgroundRotation = 0; + GLfloat selectedItemSize = 0.0f; const Q3DCamera *activeCamera = m_cachedScene->activeCamera(); + QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); + // Specify viewport glViewport(m_primarySubViewport.x(), m_primarySubViewport.y(), @@ -252,7 +268,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Set up projection matrix QMatrix4x4 projectionMatrix; - GLfloat viewPortRatio = (GLfloat)m_primarySubViewport.width() / (GLfloat)m_primarySubViewport.height(); + GLfloat viewPortRatio = (GLfloat)m_primarySubViewport.width() + / (GLfloat)m_primarySubViewport.height(); projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f); // Calculate view matrix @@ -318,7 +335,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) glEnable(GL_PROGRAM_POINT_SIZE); } - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Render scene into a depth texture for using with shadow mapping // Bind depth shader m_depthShader->bind(); @@ -340,18 +357,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QVector3D depthLightPos = activeCamera->calculatePositionRelativeToCamera( zeroVector, 0.0f, 2.5f / m_autoScaleAdjustment); depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector); - // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? - // That causes the scene to be not drawn from above -> must be fixed - // qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); // Set the depth projection matrix #ifndef USE_WIDER_SHADOWS // Use this for perspective shadows depthProjectionMatrix.perspective(15.0f, viewPortRatio, 3.0f, 100.0f); #else // Use these for orthographic shadows - //depthProjectionMatrix.ortho(-aspectRatio * 2.0f, aspectRatio * 2.0f, - // -m_heightNormalizer * 2.0f, m_heightNormalizer * 2.0f, - // 0.0f, 100.0f); GLfloat testAspectRatio = viewPortRatio; depthProjectionMatrix.ortho(-testAspectRatio * 2.0f, testAspectRatio * 2.0f, -m_heightNormalizer * 2.0f, m_heightNormalizer * 2.0f, @@ -362,12 +373,10 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Draw dots to depth buffer for (int series = 0; series < seriesCount; series++) { ObjectHelper *dotObj = m_visibleSeriesList.at(series).object(); + QQuaternion seriesRotation = m_visibleSeriesList.at(series).meshRotation(); bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint); - // TODO: Accessing series directly during rendering - float itemSize = - static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize() - / itemScaler; + float itemSize = m_cachedItemSize.at(series) / itemScaler; if (itemSize == 0.0f) itemSize = m_dotSizeScale; if (drawingPoints) { @@ -385,8 +394,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 MVPMatrix; modelMatrix.translate(item.translation()); - if (!drawingPoints) + if (!drawingPoints) { + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) + modelMatrix.rotate(seriesRotation * item.rotation()); modelMatrix.scale(modelScaler); + } MVPMatrix = depthProjectionViewMatrix * modelMatrix; @@ -428,19 +440,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) m_primarySubViewport.y(), m_primarySubViewport.width(), m_primarySubViewport.height()); - -#if 0 // Use this if you want to see what is being drawn to the framebuffer - // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it) - m_labelShader->bind(); - glEnable(GL_TEXTURE_2D); - QMatrix4x4 modelMatrix; - QMatrix4x4 viewmatrix; - viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f), zeroVector, upVector); - QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; - m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix); - m_drawer->drawObject(m_labelShader, m_labelObj, m_depthTexture); - glDisable(GL_TEXTURE_2D); -#endif } ShaderHelper *pointSelectionShader = m_selectionShader; @@ -450,10 +449,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) ShaderHelper *selectionShader = m_selectionShader; // Skip selection mode drawing if we have no selection mode - if (m_cachedSelectionMode > QDataVis::SelectionNone + if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone && SelectOnScene == m_selectionState && seriesCount > 0) { // Draw dots to selection buffer glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer); + glViewport(0, 0, + m_primarySubViewport.width(), + m_primarySubViewport.height()); + glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Set clear color to white (= skipColor) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer @@ -467,12 +470,10 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) bool previousDrawingPoints = (m_visibleSeriesList.at(0).mesh() != QAbstract3DSeries::MeshPoint); for (int series = 0; series < seriesCount; series++) { ObjectHelper *dotObj = m_visibleSeriesList.at(series).object(); + QQuaternion seriesRotation = m_visibleSeriesList.at(series).meshRotation(); bool drawingPoints = (m_visibleSeriesList.at(series).mesh() == QAbstract3DSeries::MeshPoint); - // TODO: Accessing series directly during rendering - float itemSize = - static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(series).series())->itemSize() - / itemScaler; + float itemSize = m_cachedItemSize.at(series) / itemScaler; if (itemSize == 0.0f) itemSize = m_dotSizeScale; #if !defined(QT_OPENGL_ES_2) @@ -506,8 +507,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QMatrix4x4 MVPMatrix; modelMatrix.translate(item.translation()); - if (!drawingPoints) + if (!drawingPoints) { + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) + modelMatrix.rotate(seriesRotation * item.rotation()); modelMatrix.scale(modelScaler); + } MVPMatrix = projectionViewMatrix * modelMatrix; @@ -547,25 +551,16 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Read color under cursor QVector3D clickedColor = Utils::getSelection(m_inputPosition, m_viewport.height()); - int clickedIndex = 0; - QScatter3DSeries *clickedSeries = 0; - selectionColorToSeriesAndIndex(clickedColor, clickedIndex, clickedSeries); - emit itemClicked(clickedIndex, clickedSeries); + selectionColorToSeriesAndIndex(clickedColor, m_clickedIndex, m_clickedSeries); - glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); + emit needRender(); -#if 0 // Use this if you want to see what is being drawn to the framebuffer - m_labelShader->bind(); - glDisable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - QMatrix4x4 modelMatrix; - QMatrix4x4 viewmatrix; - viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f), zeroVector, upVector); - QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; - m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix); - m_drawer->drawObject(m_labelShader, m_labelObj, m_selectionTexture); - glDisable(GL_TEXTURE_2D); -#endif + // Revert to original fbo and viewport + glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle); + glViewport(m_primarySubViewport.x(), + m_primarySubViewport.y(), + m_primarySubViewport.width(), + m_primarySubViewport.height()); } // Draw dots @@ -585,13 +580,17 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) m_dotGradientShader->bind(); m_dotGradientShader->setUniformValue(m_dotGradientShader->lightP(), lightPos); m_dotGradientShader->setUniformValue(m_dotGradientShader->view(), viewMatrix); - m_dotGradientShader->setUniformValue(m_dotGradientShader->ambientS(), m_cachedTheme->ambientLightStrength()); + m_dotGradientShader->setUniformValue(m_dotGradientShader->ambientS(), + m_cachedTheme->ambientLightStrength()); + m_dotGradientShader->setUniformValue(m_dotGradientShader->lightColor(), lightColor); } if (haveUniformColorMeshSeries) { m_dotShader->bind(); m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos); m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix); - m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme->ambientLightStrength()); + m_dotShader->setUniformValue(m_dotShader->ambientS(), + m_cachedTheme->ambientLightStrength()); + m_dotShader->setUniformValue(m_dotShader->lightColor(), lightColor); dotShader = m_dotShader; } else { dotShader = m_dotGradientShader; @@ -607,16 +606,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) for (int series = 0; series < seriesCount; series++) { const SeriesRenderCache ¤tSeries = m_visibleSeriesList.at(series); + QQuaternion seriesRotation = currentSeries.meshRotation(); ObjectHelper *dotObj = currentSeries.object(); bool drawingPoints = (currentSeries.mesh() == QAbstract3DSeries::MeshPoint); Q3DTheme::ColorStyle colorStyle = currentSeries.colorStyle(); bool colorStyleIsUniform = (colorStyle == Q3DTheme::ColorStyleUniform); bool useColor = colorStyleIsUniform || drawingPoints; - // TODO: Accessing series directly during rendering - float itemSize = - static_cast<QScatter3DSeries *>(currentSeries.series())->itemSize() - / itemScaler; + float itemSize = m_cachedItemSize.at(series) / itemScaler; if (itemSize == 0.0f) itemSize = m_dotSizeScale; #if !defined(QT_OPENGL_ES_2) @@ -671,6 +668,11 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) modelMatrix.translate(item.translation()); if (!drawingPoints) { + if (!seriesRotation.isIdentity() || !item.rotation().isIdentity()) { + QQuaternion totalRotation = seriesRotation * item.rotation(); + modelMatrix.rotate(totalRotation); + itModelMatrix.rotate(totalRotation); + } modelMatrix.scale(modelScaler); itModelMatrix.scale(modelScaler); } @@ -686,7 +688,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) gradientTexture = currentSeries.baseGradientTexture(); GLfloat lightStrength = m_cachedTheme->lightStrength(); - if (m_cachedSelectionMode > QDataVis::SelectionNone && (m_selectedItemTotalIndex == dotNo)) { + if (m_cachedSelectionMode > QAbstract3DGraph::SelectionNone + && (m_selectedItemTotalIndex == dotNo)) { if (useColor) dotColor = currentSeries.singleHighlightColor(); else @@ -695,6 +698,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one selectedItem = &item; dotSelectionFound = true; + // Save selected item size (adjusted with font size) for selection label positioning + selectedItemSize = itemSize + (m_cachedTheme->font().pointSizeF() / 500.0f); } if (!drawingPoints) { @@ -703,6 +708,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) dotShader->setUniformValue(dotShader->nModel(), itModelMatrix.inverted().transposed()); } + dotShader->setUniformValue(dotShader->MVP(), MVPMatrix); if (useColor) { dotShader->setUniformValue(dotShader->color(), dotColor); @@ -711,7 +717,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) (item.position().y() + 1.0f) / 2.0f); } #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { if (!drawingPoints) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; @@ -800,9 +806,10 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor); m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(), m_cachedTheme->ambientLightStrength() * 2.0f); + m_backgroundShader->setUniformValue(m_backgroundShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), @@ -849,8 +856,9 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->view(), viewMatrix); lineShader->setUniformValue(lineShader->color(), lineColor); lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength()); + lineShader->setUniformValue(lineShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadowed shader bindings lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->lightS(), @@ -859,11 +867,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #endif { // Set shadowless shader bindings - lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme->lightStrength() / 2.5f); + lineShader->setUniformValue(lineShader->lightS(), + m_cachedTheme->lightStrength() / 2.5f); } - QQuaternion lineYRotation = QQuaternion(); - QQuaternion lineXRotation = QQuaternion(); + QQuaternion lineYRotation; + QQuaternion lineXRotation; if (m_xFlipped) lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f); @@ -924,7 +933,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; // Set shadow shader bindings lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -976,7 +985,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1033,7 +1042,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1088,7 +1097,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1152,7 +1161,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1210,7 +1219,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1228,8 +1237,6 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) } // Draw axis labels - // TODO: Calculations done temporarily here. Should be done when calculating lines to avoid - // extra for -loops? // Bind label shader m_labelShader->bind(); @@ -1452,15 +1459,16 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Draw the selection label LabelItem &labelItem = selectedItem->selectionLabelItem(); if (m_selectedItem != selectedItem || m_updateLabels - || !labelItem.textureId()) { + || !labelItem.textureId() || m_selectionLabelDirty) { QString labelText = selectedItem->selectionLabel(); - if (labelText.isNull()) { + if (labelText.isNull() || m_selectionLabelDirty) { static const QString xTitleTag(QStringLiteral("@xTitle")); static const QString yTitleTag(QStringLiteral("@yTitle")); static const QString zTitleTag(QStringLiteral("@zTitle")); static const QString xLabelTag(QStringLiteral("@xLabel")); static const QString yLabelTag(QStringLiteral("@yLabel")); static const QString zLabelTag(QStringLiteral("@zLabel")); + static const QString seriesNameTag(QStringLiteral("@seriesName")); labelText = m_visibleSeriesList[m_selectedItemSeriesIndex].itemLabelFormat(); @@ -1492,16 +1500,19 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) selectedItem->position().z()); labelText.replace(zLabelTag, valueLabelText); } + labelText.replace(seriesNameTag, m_visibleSeriesList[m_selectedItemSeriesIndex].name()); selectedItem->setSelectionLabel(labelText); + m_selectionLabelDirty = false; } m_drawer->generateLabelItem(labelItem, labelText); m_selectedItem = selectedItem; } m_drawer->drawLabel(*selectedItem, labelItem, viewMatrix, projectionMatrix, - zeroVector, zeroVector, 0, m_cachedSelectionMode, m_labelShader, - m_labelObj, activeCamera, true, false, Drawer::LabelOver); + zeroVector, zeroVector, selectedItemSize, m_cachedSelectionMode, + m_labelShader, m_labelObj, activeCamera, true, false, + Drawer::LabelOver); // Reset label update flag; they should have been updated when we get here m_updateLabels = false; @@ -1539,31 +1550,31 @@ void Scatter3DRenderer::updateSelectedItem(int index, const QScatter3DSeries *se } } -void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) +void Scatter3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality) { m_cachedShadowQuality = quality; switch (quality) { - case QDataVis::ShadowQualityLow: + case QAbstract3DGraph::ShadowQualityLow: m_shadowQualityToShader = 33.3f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualityMedium: + case QAbstract3DGraph::ShadowQualityMedium: m_shadowQualityToShader = 100.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualityHigh: + case QAbstract3DGraph::ShadowQualityHigh: m_shadowQualityToShader = 200.0f; m_shadowQualityMultiplier = 5; break; - case QDataVis::ShadowQualitySoftLow: + case QAbstract3DGraph::ShadowQualitySoftLow: m_shadowQualityToShader = 5.0f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualitySoftMedium: + case QAbstract3DGraph::ShadowQualitySoftMedium: m_shadowQualityToShader = 10.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualitySoftHigh: + case QAbstract3DGraph::ShadowQualitySoftHigh: m_shadowQualityToShader = 15.0f; m_shadowQualityMultiplier = 4; break; @@ -1616,12 +1627,13 @@ void Scatter3DRenderer::fixMeshFileName(QString &fileName, QAbstract3DSeries::Me // Load full version of meshes that have it available if (mesh != QAbstract3DSeries::MeshSphere && mesh != QAbstract3DSeries::MeshMinimal - && mesh != QAbstract3DSeries::MeshPoint) { + && mesh != QAbstract3DSeries::MeshPoint + && mesh != QAbstract3DSeries::MeshArrow) { fileName.append(QStringLiteral("Full")); } } -void Scatter3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, +void Scatter3DRenderer::updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, float max) { Abstract3DRenderer::updateAxisRange(orientation, min, max); @@ -1659,7 +1671,8 @@ void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString & m_dotShader->initialize(); } -void Scatter3DRenderer::initGradientShaders(const QString &vertexShader, const QString &fragmentShader) +void Scatter3DRenderer::initGradientShaders(const QString &vertexShader, + const QString &fragmentShader) { if (m_dotGradientShader) delete m_dotGradientShader; @@ -1711,7 +1724,7 @@ void Scatter3DRenderer::updateDepthBuffer() if (m_primarySubViewport.size().isEmpty()) return; - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { m_depthTexture = m_textureHelper->createDepthTextureFrameBuffer(m_primarySubViewport.size(), m_depthFrameBuffer, m_shadowQualityMultiplier); @@ -1756,7 +1769,9 @@ QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index) return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue); } -void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, int &index, QScatter3DSeries *&series) +void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, + int &index, + QAbstract3DSeries *&series) { if (color != selectionSkipColor) { index = int(color.x()) @@ -1765,7 +1780,7 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, i // Find the series and adjust the index accordingly for (int i = 0; i < m_renderingArrays.size(); i++) { if (index < m_renderingArrays.at(i).size()) { - series = static_cast<QScatter3DSeries *>(m_visibleSeriesList.at(i).series()); + series = m_visibleSeriesList.at(i).series(); return; // Valid found and already set to return parameters, so we can return } else { index -= m_renderingArrays.at(i).size(); @@ -1778,4 +1793,4 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector3D &color, i series = 0; } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 30ec7489..d7a880f9 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -39,7 +39,7 @@ class QPoint; class QSizeF; class QOpenGLShaderProgram; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class ShaderHelper; class ObjectHelper; @@ -92,6 +92,8 @@ private: QVector<ScatterRenderItemArray> m_renderingArrays; GLfloat m_backgroundMargin; GLfloat m_maxItemSize; + QVector<float> m_cachedItemSize; + int m_clickedIndex; public: explicit Scatter3DRenderer(Scatter3DController *controller); @@ -101,6 +103,9 @@ public: void updateData(); void updateScene(Q3DScene *scene); + inline int clickedIndex() const { return m_clickedIndex; } + void resetClickedStatus(); + void render(GLuint defaultFboHandle); protected: @@ -109,7 +114,7 @@ protected: private: virtual void initShaders(const QString &vertexShader, const QString &fragmentShader); virtual void initGradientShaders(const QString &vertexShader, const QString &fragmentShader); - virtual void updateShadowQuality(QDataVis::ShadowQuality quality); + virtual void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality); virtual void updateTextures(); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); @@ -137,18 +142,17 @@ private: public slots: // Overloaded from abstract renderer - virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, float min, float max); + virtual void updateAxisRange(QAbstract3DAxis::AxisOrientation orientation, float min, + float max); void updateSelectedItem(int index, const QScatter3DSeries *series); -signals: - void itemClicked(int index, QScatter3DSeries *series); - private: QVector3D indexToSelectionColor(GLint index); - void selectionColorToSeriesAndIndex(const QVector3D &color, int &index, QScatter3DSeries *&series); + void selectionColorToSeriesAndIndex(const QVector3D &color, int &index, + QAbstract3DSeries *&series); }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp index c4eced30..4f5e2114 100644 --- a/src/datavisualization/engine/selectionpointer.cpp +++ b/src/datavisualization/engine/selectionpointer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -22,17 +22,13 @@ #include "objecthelper_p.h" #include "texturehelper_p.h" #include "q3dcamera.h" -#include "q3dcamera_p.h" #include "drawer_p.h" #include "utils_p.h" #include "q3dlight.h" -#include <QImage> #include <QMatrix4x4> -#include <QDebug> - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION const GLfloat sliceUnits = 2.5; @@ -114,8 +110,15 @@ void SelectionPointer::render(GLuint defaultFboHandle) // Position the pointer ball modelMatrix.translate(m_position); + if (!m_rotation.isIdentity()) { + modelMatrix.rotate(m_rotation); + itModelMatrix.rotate(m_rotation); + } + // Scale the point with fixed values (at this point) - modelMatrix.scale(QVector3D(0.05f, 0.05f, 0.05f)); + QVector3D scaleVector(0.05f, 0.05f, 0.05f); + modelMatrix.scale(scaleVector); + itModelMatrix.scale(scaleVector); MVPMatrix = projectionMatrix * viewMatrix * modelMatrix; @@ -134,8 +137,11 @@ void SelectionPointer::render(GLuint defaultFboHandle) m_pointShader->setUniformValue(m_pointShader->nModel(), itModelMatrix.inverted().transposed()); m_pointShader->setUniformValue(m_pointShader->color(), m_highlightColor); m_pointShader->setUniformValue(m_pointShader->MVP(), MVPMatrix); - m_pointShader->setUniformValue(m_pointShader->ambientS(), m_cachedTheme->ambientLightStrength()); + m_pointShader->setUniformValue(m_pointShader->ambientS(), + m_cachedTheme->ambientLightStrength()); m_pointShader->setUniformValue(m_pointShader->lightS(), m_cachedTheme->lightStrength() * 2.0f); + m_pointShader->setUniformValue(m_pointShader->lightColor(), + Utils::vectorFromColor(m_cachedTheme->lightColor())); m_drawer->drawObject(m_pointShader, m_pointObj); @@ -190,7 +196,7 @@ void SelectionPointer::render(GLuint defaultFboHandle) glEnable(GL_DEPTH_TEST); } -void SelectionPointer::setPosition(QVector3D position) +void SelectionPointer::setPosition(const QVector3D &position) { m_position = position; } @@ -201,11 +207,16 @@ void SelectionPointer::updateSliceData(bool sliceActivated, GLfloat autoScaleAdj m_autoScaleAdjustment = autoScaleAdjustment; } -void SelectionPointer::setHighlightColor(QVector3D colorVector) +void SelectionPointer::setHighlightColor(const QVector3D &colorVector) { m_highlightColor = colorVector; } +void SelectionPointer::setRotation(const QQuaternion &rotation) +{ + m_rotation = rotation; +} + void SelectionPointer::setLabel(const QString &label) { m_label = label; @@ -223,7 +234,7 @@ void SelectionPointer::handleDrawerChange() setLabel(m_label); } -void SelectionPointer::updateBoundingRect(QRect rect) +void SelectionPointer::updateBoundingRect(const QRect &rect) { m_mainViewPort = rect; } @@ -259,4 +270,4 @@ void SelectionPointer::loadLabelMesh() m_labelObj->load(); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/selectionpointer_p.h b/src/datavisualization/engine/selectionpointer_p.h index 8faeb9ac..c72b3510 100644 --- a/src/datavisualization/engine/selectionpointer_p.h +++ b/src/datavisualization/engine/selectionpointer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -26,30 +26,22 @@ // // We mean it. -#ifndef NOTIFICATIONLABEL_P_H -#define NOTIFICATIONLABEL_P_H +#ifndef SELECTIONPOINTER_P_H +#define SELECTIONPOINTER_P_H -#include <QtCore/QObject> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/QFont> -#include <QWindow> #include <QVector3D> #include "q3dscene.h" #include "datavisualizationglobal_p.h" #include "surface3dcontroller_p.h" -class QOpenGLShaderProgram; - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class ShaderHelper; class ObjectHelper; class SurfaceObject; class TextureHelper; -class Theme; class Drawer; -class Q3DCamera; class SelectionPointer : public QObject, protected QOpenGLFunctions { @@ -60,14 +52,15 @@ public: ~SelectionPointer(); void render(GLuint defaultFboHandle = 0); - void setPosition(QVector3D position); + void setPosition(const QVector3D &position); void setLabel(const QString &label); void setPointerObject(ObjectHelper *object); void handleDrawerChange(); - void updateBoundingRect(QRect rect); + void updateBoundingRect(const QRect &rect); void updateScene(Q3DScene *scene); void updateSliceData(bool sliceActivated, GLfloat autoScaleAdjustment); - void setHighlightColor(QVector3D colorVector); + void setHighlightColor(const QVector3D &colorVector); + void setRotation(const QQuaternion &rotation); private: void initializeOpenGL(); @@ -91,8 +84,9 @@ private: bool m_cachedIsSlicingActivated; GLfloat m_autoScaleAdjustment; QVector3D m_highlightColor; + QQuaternion m_rotation; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // NOTIFICATIONLABEL_P_H +#endif diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp index 04b2249d..fe2db319 100644 --- a/src/datavisualization/engine/seriesrendercache.cpp +++ b/src/datavisualization/engine/seriesrendercache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -22,7 +22,7 @@ #include "texturehelper_p.h" #include "utils_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION const QString smoothString(QStringLiteral("Smooth")); @@ -96,6 +96,9 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer * case QAbstract3DSeries::MeshMinimal: meshFileName = QStringLiteral(":/defaultMeshes/minimal"); break; + case QAbstract3DSeries::MeshArrow: + meshFileName = QStringLiteral(":/defaultMeshes/arrow"); + break; case QAbstract3DSeries::MeshPoint: #if defined(QT_OPENGL_ES_2) qWarning("QAbstract3DSeries::MeshPoint is not fully supported on OpenGL ES2"); @@ -114,7 +117,6 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer * renderer->fixMeshFileName(meshFileName, m_mesh); } - // TODO: Optimize by having some kind of object cache in renderer instead of having separate ObjectHelper for each series? delete m_object; if (meshFileName.isEmpty()) { m_object = 0; @@ -124,6 +126,11 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer * } } + if (seriesChanged || changeTracker.meshRotationChanged) { + m_meshRotation = series->meshRotation(); + changeTracker.meshRotationChanged = false; + } + if (seriesChanged || changeTracker.colorStyleChanged) { m_colorStyle = series->colorStyle(); changeTracker.colorStyleChanged = false; @@ -161,6 +168,11 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer * renderer->fixGradientAndGenerateTexture(&gradient, &m_multiHighlightGradientTexture); changeTracker.multiHighlightGradientChanged = false; } + + if (seriesChanged || changeTracker.nameChanged) { + m_name = series->name(); + changeTracker.nameChanged = false; + } } void SeriesRenderCache::cleanup(TextureHelper *texHelper) @@ -171,4 +183,4 @@ void SeriesRenderCache::cleanup(TextureHelper *texHelper) texHelper->deleteTexture(&m_multiHighlightGradientTexture); } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h index 906a6c0d..82f69ccd 100644 --- a/src/datavisualization/engine/seriesrendercache_p.h +++ b/src/datavisualization/engine/seriesrendercache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,7 +32,7 @@ #include "datavisualizationglobal_p.h" #include "qabstract3dseries_p.h" -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Abstract3DRenderer; class ObjectHelper; @@ -53,6 +53,8 @@ public: inline const QString &itemLabelFormat() const { return m_itemLabelFormat; } inline const QAbstract3DSeries::Mesh &mesh() const { return m_mesh; } + inline const QQuaternion &meshRotation() const { return m_meshRotation; } + inline void setMeshRotation(const QQuaternion &rotation) { m_meshRotation = rotation; } inline ObjectHelper *object() const { return m_object; } inline const Q3DTheme::ColorStyle &colorStyle() const { return m_colorStyle; } inline const QVector3D &baseColor() const { return m_baseColor; } @@ -61,12 +63,14 @@ public: inline const GLuint &singleHighlightGradientTexture() const { return m_singleHighlightGradientTexture; } inline const QVector3D &multiHighlightColor() const { return m_multiHighlightColor; } inline const GLuint &multiHighlightGradientTexture() const { return m_multiHighlightGradientTexture; } + inline const QString &name() const { return m_name; } protected: QAbstract3DSeries *m_series; QString m_itemLabelFormat; ObjectHelper *m_object; QAbstract3DSeries::Mesh m_mesh; + QQuaternion m_meshRotation; Q3DTheme::ColorStyle m_colorStyle; QVector3D m_baseColor; @@ -75,9 +79,11 @@ protected: GLuint m_singleHighlightGradientTexture; QVector3D m_multiHighlightColor; GLuint m_multiHighlightGradientTexture; + + QString m_name; }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION #endif diff --git a/src/datavisualization/engine/shaders/colorOnY.frag b/src/datavisualization/engine/shaders/colorOnY.frag index caea959b..8c610cd7 100644 --- a/src/datavisualization/engine/shaders/colorOnY.frag +++ b/src/datavisualization/engine/shaders/colorOnY.frag @@ -6,6 +6,7 @@ uniform highp float ambientStrength; uniform sampler2D textureSampler; uniform highp float gradMin; uniform highp float gradHeight; +uniform highp vec3 lightColor; varying highp vec3 position_wrld; varying highp vec3 normal_cmr; @@ -16,8 +17,8 @@ varying highp vec2 coords_mdl; void main() { highp vec2 gradientUV = vec2(0.0, gradMin + ((coords_mdl.y + 1.0) * gradHeight)); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); highp vec3 n = normalize(normal_cmr); diff --git a/src/datavisualization/engine/shaders/colorOnY_ES2.frag b/src/datavisualization/engine/shaders/colorOnY_ES2.frag index bb6e28c7..5b553562 100644 --- a/src/datavisualization/engine/shaders/colorOnY_ES2.frag +++ b/src/datavisualization/engine/shaders/colorOnY_ES2.frag @@ -4,6 +4,7 @@ uniform highp float ambientStrength; uniform sampler2D textureSampler; uniform highp float gradMin; uniform highp float gradHeight; +uniform highp vec3 lightColor; varying highp vec3 position_wrld; varying highp vec3 normal_cmr; @@ -14,8 +15,8 @@ varying highp vec2 coords_mdl; void main() { highp vec2 gradientUV = vec2(0.0, gradMin + ((coords_mdl.y + 1.0) * gradHeight)); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); highp vec3 n = normalize(normal_cmr); diff --git a/src/datavisualization/engine/shaders/default.frag b/src/datavisualization/engine/shaders/default.frag index fba1ce4a..ca6fefb9 100644 --- a/src/datavisualization/engine/shaders/default.frag +++ b/src/datavisualization/engine/shaders/default.frag @@ -11,11 +11,12 @@ uniform highp vec3 lightPosition_wrld; uniform highp vec3 color_mdl; uniform highp float lightStrength; uniform highp float ambientStrength; +uniform highp vec3 lightColor; void main() { highp vec3 materialDiffuseColor = color_mdl.rgb; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); diff --git a/src/datavisualization/engine/shaders/default_ES2.frag b/src/datavisualization/engine/shaders/default_ES2.frag index 7d6214b2..bc5c18b6 100644 --- a/src/datavisualization/engine/shaders/default_ES2.frag +++ b/src/datavisualization/engine/shaders/default_ES2.frag @@ -9,11 +9,12 @@ uniform highp vec3 lightPosition_wrld; uniform highp vec3 color_mdl; uniform highp float lightStrength; uniform highp float ambientStrength; +uniform highp vec3 lightColor; void main() { highp vec3 materialDiffuseColor = color_mdl.rgb; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); diff --git a/src/datavisualization/engine/shaders/shadow.frag b/src/datavisualization/engine/shaders/shadow.frag index 5309b5bb..e2286dc5 100644 --- a/src/datavisualization/engine/shaders/shadow.frag +++ b/src/datavisualization/engine/shaders/shadow.frag @@ -5,6 +5,7 @@ uniform highp float ambientStrength; uniform highp float shadowQuality; uniform highp sampler2D textureSampler; uniform highp sampler2DShadow shadowMap; +uniform highp vec3 lightColor; varying highp vec4 shadowCoord; varying highp vec2 UV; @@ -30,16 +31,10 @@ highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), vec2(0.19984126, 0.78641367), vec2(0.14383161, -0.14100790)); -/*float random(vec3 seed, int i) { - vec4 seed4 = vec4(seed, i); - float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673)); - return fract(sin(dot_product) * 43758.5453); -}*/ - void main() { highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(0.2, 0.2, 0.2); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor * 0.2; highp vec3 n = normalize(normal_cmr); highp vec3 l = normalize(lightDirection_cmr); @@ -54,10 +49,7 @@ void main() { vec4 shadCoords = shadowCoord; shadCoords.z -= bias; - // adjust shadow strength by increasing the multiplier and lowering the addition (their sum must be 1) - // direct method; needs large shadow texture to look good - //highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25; - // poisson disk sampling; smoothes edges + highp float visibility = 0.6; for (int i = 0; i < 15; i++) { vec4 shadCoordsPD = shadCoords; @@ -65,18 +57,11 @@ void main() { shadCoordsPD.y += sin(poissonDisk[i].y) / shadowQuality; visibility += 0.025 * shadow2DProj(shadowMap, shadCoordsPD).r; } - // stratified poisson; produces noise but hides pixel edges well - /*for (int i = 0; i < 15; i++) { - vec4 shadCoordsPD = shadCoords; - int index = int(16.0 * random(gl_FragCoord.xyy, i)); - shadCoordsPD.xy += poissonDisk[index] / 150.0; - visibility += 0.05 * shadow2DProj(shadowMap, shadCoordsPD).r; - } - */ gl_FragColor.rgb = - visibility * (materialAmbientColor + + (materialAmbientColor + materialDiffuseColor * lightStrength * cosTheta + materialSpecularColor * lightStrength * pow(cosAlpha, 10)); gl_FragColor.a = texture2D(textureSampler, UV).a; + gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0); } diff --git a/src/datavisualization/engine/shaders/shadowNoTex.frag b/src/datavisualization/engine/shaders/shadowNoTex.frag index 0252ba49..d54efea9 100644 --- a/src/datavisualization/engine/shaders/shadowNoTex.frag +++ b/src/datavisualization/engine/shaders/shadowNoTex.frag @@ -5,6 +5,7 @@ uniform highp float ambientStrength; uniform highp float shadowQuality; uniform highp vec3 color_mdl; uniform highp sampler2DShadow shadowMap; +uniform highp vec3 lightColor; varying highp vec4 shadowCoord; varying highp vec3 position_wrld; @@ -29,33 +30,10 @@ highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), vec2(0.19984126, 0.78641367), vec2(0.14383161, -0.14100790)); -/*highp vec2 poissonDisk[16] = vec2[16](vec2(-0.25, -0.25), - vec2(0.25, -0.25), - vec2(-0.25, 0.25), - vec2(0.25, 0.25), - vec2(-0.5, -0.5), - vec2(0.5, -0.5), - vec2(-0.5, 0.5), - vec2(0.5, 0.5), - vec2(-0.75, -0.75), - vec2(0.75, -0.75), - vec2(-0.75, 0.75), - vec2(0.75, 0.75), - vec2(-1.0, -1.0), - vec2(1.0, -1.0), - vec2(-1.0, 1.0), - vec2(1.0, 1.0));*/ - -/*float random(vec3 seed, int i) { - vec4 seed4 = vec4(seed, i); - float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673)); - return fract(sin(dot_product) * 43758.5453); -}*/ - void main() { highp vec3 materialDiffuseColor = color_mdl.rgb; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp vec3 n = normalize(normal_cmr); highp vec3 l = normalize(lightDirection_cmr); @@ -70,10 +48,7 @@ void main() { vec4 shadCoords = shadowCoord; shadCoords.z -= bias; - // adjust shadow strength by increasing the multiplier and lowering the addition (their sum must be 1) - // direct method; needs large shadow texture to look good - //highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25; - // poisson disk sampling; smoothes edges + highp float visibility = 0.6; for (int i = 0; i < 15; i++) { vec4 shadCoordsPD = shadCoords; @@ -81,18 +56,11 @@ void main() { shadCoordsPD.y += sin(poissonDisk[i].y) / shadowQuality; visibility += 0.025 * shadow2DProj(shadowMap, shadCoordsPD).r; } - // stratified poisson; produces noise but hides pixel edges well - /*for (int i = 0; i < 15; i++) { - vec4 shadCoordsPD = shadCoords; - int index = int(16.0 * random(gl_FragCoord.xyy, i)); - shadCoordsPD.xy += poissonDisk[index] / 150.0; - visibility += 0.05 * shadow2DProj(shadowMap, shadCoordsPD).r; - } - */ gl_FragColor.rgb = - visibility * (materialAmbientColor + + (materialAmbientColor + materialDiffuseColor * lightStrength * cosTheta + materialSpecularColor * lightStrength * pow(cosAlpha, 10)); gl_FragColor.a = 1.0; + gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0); } diff --git a/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag b/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag index 9882cd92..e986a52a 100644 --- a/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag +++ b/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag @@ -7,6 +7,7 @@ uniform highp sampler2DShadow shadowMap; uniform sampler2D textureSampler; uniform highp float gradMin; uniform highp float gradHeight; +uniform highp vec3 lightColor; varying highp vec4 shadowCoord; varying highp vec3 position_wrld; @@ -32,17 +33,11 @@ highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), vec2(0.19984126, 0.78641367), vec2(0.14383161, -0.14100790)); -/*float random(vec3 seed, int i) { - vec4 seed4 = vec4(seed, i); - float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673)); - return fract(sin(dot_product) * 43758.5453); -}*/ - void main() { highp vec2 gradientUV = vec2(0.0, gradMin + ((coords_mdl.y + 1.0) * gradHeight)); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp vec3 n = normalize(normal_cmr); highp vec3 l = normalize(lightDirection_cmr); @@ -57,10 +52,7 @@ void main() { vec4 shadCoords = shadowCoord; shadCoords.z -= bias; - // adjust shadow strength by increasing the multiplier and lowering the addition (their sum must be 1) - // direct method; needs large shadow texture to look good - //highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25; - // poisson disk sampling; smoothes edges + highp float visibility = 0.6; for (int i = 0; i < 15; i++) { vec4 shadCoordsPD = shadCoords; @@ -68,17 +60,11 @@ void main() { shadCoordsPD.y += sin(poissonDisk[i].y) / shadowQuality; visibility += 0.025 * shadow2DProj(shadowMap, shadCoordsPD).r; } - /*for (int i = 0; i < 15; i++) { - vec4 shadCoordsPD = shadCoords; - int index = int(16.0 * random(gl_FragCoord.xyy, i)); - shadCoordsPD.xy += poissonDisk[index] / 150.0; - visibility += 0.05 * shadow2DProj(shadowMap, shadCoordsPD).r; - }*/ gl_FragColor.rgb = - visibility * (materialAmbientColor + + (materialAmbientColor + materialDiffuseColor * lightStrength * cosTheta + materialSpecularColor * lightStrength * pow(cosAlpha, 10)); - gl_FragColor.rgb = clamp(gl_FragColor.rgb, 0.0, 1.0); gl_FragColor.a = 1.0; + gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0); } diff --git a/src/datavisualization/engine/shaders/surface.frag b/src/datavisualization/engine/shaders/surface.frag index 576cc51f..b5205d2d 100644 --- a/src/datavisualization/engine/shaders/surface.frag +++ b/src/datavisualization/engine/shaders/surface.frag @@ -10,12 +10,13 @@ uniform sampler2D textureSampler; uniform highp vec3 lightPosition_wrld; uniform highp float lightStrength; uniform highp float ambientStrength; +uniform highp vec3 lightColor; void main() { highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.0) / 2.0); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); diff --git a/src/datavisualization/engine/shaders/surfaceFlat.frag b/src/datavisualization/engine/shaders/surfaceFlat.frag index fd42a289..7eaa917f 100644 --- a/src/datavisualization/engine/shaders/surfaceFlat.frag +++ b/src/datavisualization/engine/shaders/surfaceFlat.frag @@ -12,12 +12,13 @@ uniform sampler2D textureSampler; uniform highp vec3 lightPosition_wrld; uniform highp float lightStrength; uniform highp float ambientStrength; +uniform highp vec3 lightColor; void main() { highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.0) / 2.0); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); diff --git a/src/datavisualization/engine/shaders/surfaceShadowFlat.frag b/src/datavisualization/engine/shaders/surfaceShadowFlat.frag index 6341136e..9b9305ab 100644 --- a/src/datavisualization/engine/shaders/surfaceShadowFlat.frag +++ b/src/datavisualization/engine/shaders/surfaceShadowFlat.frag @@ -15,6 +15,7 @@ uniform highp vec3 lightPosition_wrld; uniform highp float lightStrength; uniform highp float ambientStrength; uniform highp float shadowQuality; +uniform highp vec3 lightColor; highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), vec2(0.94558609, -0.76890725), @@ -36,8 +37,8 @@ highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), void main() { highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.0) / 2.0); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp vec3 n = normalize(normal_cmr); highp vec3 l = normalize(lightDirection_cmr); @@ -62,9 +63,10 @@ void main() { } gl_FragColor.rgb = - visibility * (materialAmbientColor + + (materialAmbientColor + materialDiffuseColor * lightStrength * cosTheta + materialSpecularColor * lightStrength * pow(cosAlpha, 10)); gl_FragColor.a = 1.0; + gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0); } diff --git a/src/datavisualization/engine/shaders/surfaceShadowNoTex.frag b/src/datavisualization/engine/shaders/surfaceShadowNoTex.frag index 755be3f1..3427fbae 100644 --- a/src/datavisualization/engine/shaders/surfaceShadowNoTex.frag +++ b/src/datavisualization/engine/shaders/surfaceShadowNoTex.frag @@ -13,6 +13,7 @@ uniform highp vec3 lightPosition_wrld; uniform highp float lightStrength; uniform highp float ambientStrength; uniform highp float shadowQuality; +uniform highp vec3 lightColor; highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), vec2(0.94558609, -0.76890725), @@ -34,8 +35,8 @@ highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216), void main() { highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.0) / 2.0); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp vec3 n = normalize(normal_cmr); highp vec3 l = normalize(lightDirection_cmr); @@ -60,9 +61,10 @@ void main() { } gl_FragColor.rgb = - visibility * (materialAmbientColor + + (materialAmbientColor + materialDiffuseColor * lightStrength * cosTheta + materialSpecularColor * lightStrength * pow(cosAlpha, 10)); gl_FragColor.a = 1.0; + gl_FragColor.rgb = visibility * clamp(gl_FragColor.rgb, 0.0, 1.0); } diff --git a/src/datavisualization/engine/shaders/surface_ES2.frag b/src/datavisualization/engine/shaders/surface_ES2.frag index c7e75594..0e17cacd 100644 --- a/src/datavisualization/engine/shaders/surface_ES2.frag +++ b/src/datavisualization/engine/shaders/surface_ES2.frag @@ -9,12 +9,13 @@ uniform sampler2D textureSampler; uniform highp vec3 lightPosition_wrld; uniform highp float lightStrength; uniform highp float ambientStrength; +uniform highp vec3 lightColor; void main() { highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.0) / 2.0); highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz; - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + highp vec3 materialAmbientColor = lightColor * ambientStrength * materialDiffuseColor; + highp vec3 materialSpecularColor = lightColor; highp float distance = length(lightPosition_wrld - position_wrld); diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp index 3cec72d1..0eb66d0e 100644 --- a/src/datavisualization/engine/surface3dcontroller.cpp +++ b/src/datavisualization/engine/surface3dcontroller.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -19,9 +19,9 @@ #include "surface3dcontroller_p.h" #include "surface3drenderer_p.h" #include "camerahelper_p.h" -#include "q3dabstractaxis_p.h" -#include "q3dvalueaxis_p.h" -#include "q3dcategoryaxis.h" +#include "qabstract3daxis_p.h" +#include "qvalue3daxis_p.h" +#include "qcategory3daxis.h" #include "qsurfacedataproxy_p.h" #include "qsurface3dseries_p.h" #include "shaderhelper_p.h" @@ -30,10 +30,10 @@ #include <QDebug> -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION -Surface3DController::Surface3DController(QRect rect) - : Abstract3DController(rect), +Surface3DController::Surface3DController(QRect rect, Q3DScene *scene) + : Abstract3DController(rect, scene), m_renderer(0), m_selectedPoint(invalidSelectionPosition()), m_selectedSeries(0), @@ -59,9 +59,7 @@ void Surface3DController::initializeOpenGL() m_renderer = new Surface3DRenderer(this); setRenderer(m_renderer); - synchDataToRenderer(); - QObject::connect(m_renderer, &Surface3DRenderer::pointClicked, this, - &Surface3DController::handlePointClicked, Qt::QueuedConnection); + emitNeedRender(); } @@ -91,7 +89,8 @@ void Surface3DController::synchDataToRenderer() } } -void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) +void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation( + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) { Q_UNUSED(orientation) Q_UNUSED(autoAdjust) @@ -111,11 +110,24 @@ void Surface3DController::handleSeriesVisibilityChangedBySender(QObject *sender) { Abstract3DController::handleSeriesVisibilityChangedBySender(sender); + adjustValueAxisRange(); + // Visibility changes may require disabling/enabling slicing, // so just reset selection to ensure everything is still valid. setSelectedPoint(m_selectedPoint, m_selectedSeries); } +void Surface3DController::handlePendingClick() +{ + // This function is called while doing the sync, so it is okay to query from renderer + QPoint position = m_renderer->clickedPosition(); + QSurface3DSeries *series = static_cast<QSurface3DSeries *>(m_renderer->clickedSeries()); + + setSelectedPoint(position, series); + + m_renderer->resetClickedStatus(); +} + QPoint Surface3DController::invalidSelectionPosition() { static QPoint invalidSelectionPoint(-1, -1); @@ -134,7 +146,8 @@ void Surface3DController::addSeries(QAbstract3DSeries *series) if (!m_seriesList.size()) { Abstract3DController::addSeries(series); - adjustValueAxisRange(); + if (series->isVisible()) + adjustValueAxisRange(); } else { qWarning("Surface graph only supports a single series."); } @@ -146,14 +159,15 @@ void Surface3DController::addSeries(QAbstract3DSeries *series) void Surface3DController::removeSeries(QAbstract3DSeries *series) { - if (series && series->d_ptr->m_controller == this) { - Abstract3DController::removeSeries(series); + bool wasVisible = (series && series->d_ptr->m_controller == this && series->isVisible()); + + Abstract3DController::removeSeries(series); - if (m_selectedSeries == series) - setSelectedPoint(invalidSelectionPosition(), 0); + if (m_selectedSeries == series) + setSelectedPoint(invalidSelectionPosition(), 0); + if (wasVisible) adjustValueAxisRange(); - } } QList<QSurface3DSeries *> Surface3DController::surfaceSeriesList() @@ -169,18 +183,20 @@ QList<QSurface3DSeries *> Surface3DController::surfaceSeriesList() return surfaceSeriesList; } -void Surface3DController::setSelectionMode(QDataVis::SelectionFlags mode) +void Surface3DController::setSelectionMode(QAbstract3DGraph::SelectionFlags mode) { // Currently surface only supports row and column modes when also slicing - if ((mode.testFlag(QDataVis::SelectionRow) || mode.testFlag(QDataVis::SelectionColumn)) - && !mode.testFlag(QDataVis::SelectionSlice)) { + if ((mode.testFlag(QAbstract3DGraph::SelectionRow) + || mode.testFlag(QAbstract3DGraph::SelectionColumn)) + && !mode.testFlag(QAbstract3DGraph::SelectionSlice)) { qWarning("Unsupported selection mode."); return; - } else if (mode.testFlag(QDataVis::SelectionSlice) - && (mode.testFlag(QDataVis::SelectionRow) == mode.testFlag(QDataVis::SelectionColumn))) { + } else if (mode.testFlag(QAbstract3DGraph::SelectionSlice) + && (mode.testFlag(QAbstract3DGraph::SelectionRow) + == mode.testFlag(QAbstract3DGraph::SelectionColumn))) { qWarning("Must specify one of either row or column selection mode in conjunction with slicing mode."); } else { - QDataVis::SelectionFlags oldMode = selectionMode(); + QAbstract3DGraph::SelectionFlags oldMode = selectionMode(); Abstract3DController::setSelectionMode(mode); @@ -191,8 +207,8 @@ void Surface3DController::setSelectionMode(QDataVis::SelectionFlags mode) // Special case: Always deactivate slicing when changing away from slice // automanagement, as this can't be handled in setSelectedBar. - if (!mode.testFlag(QDataVis::SelectionSlice) - && oldMode.testFlag(QDataVis::SelectionSlice)) { + if (!mode.testFlag(QAbstract3DGraph::SelectionSlice) + && oldMode.testFlag(QAbstract3DGraph::SelectionSlice)) { scene()->setSlicingActive(false); } } @@ -223,13 +239,11 @@ void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSer pos = invalidSelectionPosition(); } - if (selectionMode().testFlag(QDataVis::SelectionSlice)) { + if (selectionMode().testFlag(QAbstract3DGraph::SelectionSlice)) { if (pos == invalidSelectionPosition() || !series->isVisible()) { scene()->setSlicingActive(false); } else { // If the selected point is outside data window, or there is no selected point, disable slicing - // TODO: (QTRD-2351) This logic doesn't match the renderer logic for non straight surfaces, - // but that logic needs to change anyway, so this is good for now. float axisMinX = m_axisX->min(); float axisMaxX = m_axisX->max(); float axisMinZ = m_axisZ->min(); @@ -264,22 +278,23 @@ void Surface3DController::setSelectedPoint(const QPoint &position, QSurface3DSer } } +void Surface3DController::clearSelection() +{ + setSelectedPoint(invalidSelectionPosition(), 0); +} + void Surface3DController::handleArrayReset() { - adjustValueAxisRange(); - m_isDataDirty = true; + QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } // Clear selection unless still valid setSelectedPoint(m_selectedPoint, m_selectedSeries); emitNeedRender(); } -void Surface3DController::handlePointClicked(const QPoint &position, QSurface3DSeries *series) -{ - setSelectedPoint(position, series); - // TODO: pass clicked to parent. (QTRD-2517) - // TODO: Also hover needed? (QTRD-2131) -} - void Surface3DController::handleFlatShadingSupportedChange(bool supported) { // Handle renderer flat surface support indicator signal. This happens exactly once per renderer. @@ -299,7 +314,8 @@ void Surface3DController::handleRowsChanged(int startIndex, int count) if (m_changedRows.size() == 0) m_changedRows.reserve(sender->rowCount()); - if (static_cast<QSurface3DSeries *>(m_seriesList.at(0)) == sender->series()) { + QSurface3DSeries *series = sender->series(); + if (series->isVisible()) { // Change is for the visible series, put the change to queue int oldChangeCount = m_changedRows.size(); for (int i = 0; i < count; i++) { @@ -328,7 +344,8 @@ void Surface3DController::handleRowsChanged(int startIndex, int count) void Surface3DController::handleItemChanged(int rowIndex, int columnIndex) { QSurfaceDataProxy *sender = static_cast<QSurfaceDataProxy *>(QObject::sender()); - if (static_cast<QSurface3DSeries *>(m_seriesList.at(0)) == sender->series()) { + QSurface3DSeries *series = sender->series(); + if (series->isVisible()) { // Change is for the visible series, put the change to queue bool newItem = true; QPoint candidate(columnIndex, rowIndex); @@ -354,8 +371,11 @@ void Surface3DController::handleRowsAdded(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustValueAxisRange(); - m_isDataDirty = true; + QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series(); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } emitNeedRender(); } @@ -363,8 +383,21 @@ void Surface3DController::handleRowsInserted(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustValueAxisRange(); - m_isDataDirty = true; + QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series(); + if (series == m_selectedSeries) { + // If rows inserted to selected series before the selection, adjust the selection + int selectedRow = m_selectedPoint.x(); + if (startIndex <= selectedRow) { + selectedRow += count; + setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries); + } + } + + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } + emitNeedRender(); } @@ -372,20 +405,33 @@ void Surface3DController::handleRowsRemoved(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - adjustValueAxisRange(); - m_isDataDirty = true; + QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(sender())->series(); + if (series == m_selectedSeries) { + // If rows removed from selected series before the selection, adjust the selection + int selectedRow = m_selectedPoint.x(); + if (startIndex <= selectedRow) { + if ((startIndex + count) > selectedRow) + selectedRow = -1; // Selected row removed + else + selectedRow -= count; // Move selected row down by amount of rows removed + + setSelectedPoint(QPoint(selectedRow, m_selectedPoint.y()), m_selectedSeries); + } + } - // Clear selection unless still valid - setSelectedPoint(m_selectedPoint, m_selectedSeries); + if (series->isVisible()) { + adjustValueAxisRange(); + m_isDataDirty = true; + } emitNeedRender(); } void Surface3DController::adjustValueAxisRange() { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); + QValue3DAxis *valueAxisX = static_cast<QValue3DAxis *>(m_axisX); + QValue3DAxis *valueAxisY = static_cast<QValue3DAxis *>(m_axisY); + QValue3DAxis *valueAxisZ = static_cast<QValue3DAxis *>(m_axisZ); bool adjustX = (valueAxisX && valueAxisX->isAutoAdjustRange()); bool adjustY = (valueAxisY && valueAxisY->isAutoAdjustRange()); bool adjustZ = (valueAxisZ && valueAxisZ->isAutoAdjustRange()); @@ -491,4 +537,4 @@ void Surface3DController::adjustValueAxisRange() } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h index 714420a4..624bea47 100644 --- a/src/datavisualization/engine/surface3dcontroller_p.h +++ b/src/datavisualization/engine/surface3dcontroller_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -32,8 +32,7 @@ #include "abstract3dcontroller_p.h" #include "datavisualizationglobal_p.h" - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class Surface3DRenderer; class QSurface3DSeries; @@ -70,18 +69,21 @@ private: QVector<int> m_changedRows; public: - explicit Surface3DController(QRect rect); + explicit Surface3DController(QRect rect, Q3DScene *scene = 0); ~Surface3DController(); virtual void initializeOpenGL(); virtual void synchDataToRenderer(); - void setSelectionMode(QDataVis::SelectionFlags mode); + void setSelectionMode(QAbstract3DGraph::SelectionFlags mode); void setSelectedPoint(const QPoint &position, QSurface3DSeries *series); + virtual void clearSelection(); - virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust); + virtual void handleAxisAutoAdjustRangeChangedInOrientation( + QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust); virtual void handleAxisRangeChangedBySender(QObject *sender); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); + virtual void handlePendingClick(); static QPoint invalidSelectionPosition(); bool isFlatShadingSupported(); @@ -98,9 +100,6 @@ public slots: void handleRowsInserted(int startIndex, int count); void handleItemChanged(int rowIndex, int columnIndex); - // Renderer callback handlers - void handlePointClicked(const QPoint &position, QSurface3DSeries *series); - void handleFlatShadingSupportedChange(bool supported); private: @@ -109,6 +108,6 @@ private: Q_DISABLE_COPY(Surface3DController) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // SURFACE3DCONTROLLER_P_H +#endif diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 912edd97..82f9eae1 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -38,13 +38,10 @@ static const int ID_TO_RGBA_MASK = 0xff; -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION //#define SHOW_DEPTH_TEXTURE_SCENE -// TODO Uniform scaling is broken on surface -//#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values - const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd. const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background) const GLfloat labelMargin = 0.05f; @@ -61,7 +58,6 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_font(QFont(QStringLiteral("Arial"))), m_isGridEnabled(true), m_cachedIsSlicingActivated(false), - m_shader(0), m_depthShader(0), m_backgroundShader(0), m_surfaceShader(0), @@ -90,6 +86,7 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_surfaceObj(0), m_sliceSurfaceObj(0), m_depthTexture(0), + m_depthModelTexture(0), m_depthFrameBuffer(0), m_selectionFrameBuffer(0), m_selectionDepthBuffer(0), @@ -111,7 +108,8 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_hasHeightAdjustmentChanged(true), m_selectedPoint(Surface3DController::invalidSelectionPosition()), m_selectedSeries(0), - m_uniformGradientTexture(0) + m_uniformGradientTexture(0), + m_clickedPosition(Surface3DController::invalidSelectionPosition()) { // Check if flat feature is supported ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"), @@ -145,7 +143,6 @@ Surface3DRenderer::~Surface3DRenderer() m_textureHelper->deleteTexture(&m_selectionResultTexture); m_textureHelper->deleteTexture(&m_uniformGradientTexture); } - delete m_shader; delete m_depthShader; delete m_backgroundShader; delete m_selectionShader; @@ -228,7 +225,6 @@ void Surface3DRenderer::updateData() m_dataArray.clear(); } - // TODO: Handle partial surface grids on the graph edges if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) { if (dimensionChanged) { m_dataArray.reserve(sampleSpace.height()); @@ -237,7 +233,8 @@ void Surface3DRenderer::updateData() } for (int i = 0; i < sampleSpace.height(); i++) { for (int j = 0; j < sampleSpace.width(); j++) - (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at(j + sampleSpace.x()); + (*(m_dataArray.at(i)))[j] = array->at(i + sampleSpace.y())->at( + j + sampleSpace.x()); } if (m_dataArray.size() > 0) { @@ -278,12 +275,11 @@ void Surface3DRenderer::updateData() updateSelectedPoint(m_selectedPoint, m_selectedSeries); } -void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList, bool updateVisibility) +void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList, + bool updateVisibility) { Abstract3DRenderer::updateSeries(seriesList, updateVisibility); - // TODO: move to render cache when multiseries support implemented QTRD-2657 - // TODO: until then just update them always. if (m_visibleSeriesList.size()) { QSurface3DSeries *series = static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series()); updateFlatStatus(series->isFlatShadingEnabled()); @@ -302,9 +298,11 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis if (m_uniformGradientTextureColor != seriesColor) generateUniformGradient(seriesColor); if (m_selectionPointer) { - m_selectionPointer->setHighlightColor(Utils::vectorFromColor(series->singleHighlightColor())); + m_selectionPointer->setHighlightColor( + Utils::vectorFromColor(series->singleHighlightColor())); // Make sure selection pointer object reference is still good m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object()); + m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation()); } } } @@ -320,8 +318,8 @@ void Surface3DRenderer::updateRows(const QVector<int> &rows) array = dataProxy->array(); } - if (array && array->size() >= 2 && array->at(0)->size() >= 2 && - m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) { + if (array && array->size() >= 2 && array->at(0)->size() >= 2 + && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) { bool updateBuffers = false; int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height(); foreach (int row, rows) { @@ -332,10 +330,12 @@ void Surface3DRenderer::updateRows(const QVector<int> &rows) array->at(row)->at(j + m_sampleSpace.x()); if (m_cachedFlatShading) { - m_surfaceObj->updateCoarseRow(m_dataArray, row - m_sampleSpace.y(), m_heightNormalizer, + m_surfaceObj->updateCoarseRow(m_dataArray, row - m_sampleSpace.y(), + m_heightNormalizer, m_axisCacheY.min()); } else { - m_surfaceObj->updateSmoothRow(m_dataArray, row - m_sampleSpace.y(), m_heightNormalizer, + m_surfaceObj->updateSmoothRow(m_dataArray, row - m_sampleSpace.y(), + m_heightNormalizer, m_axisCacheY.min()); } } @@ -349,8 +349,6 @@ void Surface3DRenderer::updateRows(const QVector<int> &rows) void Surface3DRenderer::updateItem(const QVector<QPoint> &points) { - // TODO: Properly support non-straight rows and columns (QTRD-2643) - // Surface only supports single series for now, so we are only interested in the first series const QSurfaceDataArray *array = 0; if (m_visibleSeriesList.size()) { @@ -360,23 +358,25 @@ void Surface3DRenderer::updateItem(const QVector<QPoint> &points) array = dataProxy->array(); } - if (array && array->size() >= 2 && array->at(0)->size() >= 2 && - m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) { + if (array && array->size() >= 2 && array->at(0)->size() >= 2 + && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) { int sampleSpaceTop = m_sampleSpace.y() + m_sampleSpace.height(); int sampleSpaceRight = m_sampleSpace.x() + m_sampleSpace.width(); bool updateBuffers = false; foreach (QPoint item, points) { if (item.y() <= sampleSpaceTop && item.y() >= m_sampleSpace.y() && - item.x() <= sampleSpaceRight && item.x() >= m_sampleSpace.x()) { + item.x() <= sampleSpaceRight && item.x() >= m_sampleSpace.x()) { updateBuffers = true; int x = item.x() - m_sampleSpace.x(); int y = item.y() - m_sampleSpace.y(); (*(m_dataArray.at(y)))[x] = array->at(item.y())->at(item.x()); if (m_cachedFlatShading) { - m_surfaceObj->updateCoarseItem(m_dataArray, y, x, m_heightNormalizer, m_axisCacheY.min()); + m_surfaceObj->updateCoarseItem(m_dataArray, y, x, m_heightNormalizer, + m_axisCacheY.min()); } else { - m_surfaceObj->updateSmoothItem(m_dataArray, y, x, m_heightNormalizer, m_axisCacheY.min()); + m_surfaceObj->updateSmoothItem(m_dataArray, y, x, m_heightNormalizer, + m_axisCacheY.min()); } } } @@ -401,7 +401,7 @@ void Surface3DRenderer::updateSliceDataModel(const QPoint &point) float adjust = (0.025f * m_heightNormalizer) / 2.0f; float stepDown = 2.0f * adjust; - if (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow)) { + if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) { QSurfaceDataRow *src = m_dataArray.at(row); sliceRow = new QSurfaceDataRow(src->size()); for (int i = 0; i < sliceRow->size(); i++) @@ -419,8 +419,10 @@ void Surface3DRenderer::updateSliceDataModel(const QPoint &point) // Make a duplicate, so that we get a little bit depth QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow); - for (int i = 0; i < sliceRow->size(); i++) - (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown, 1.0f)); + for (int i = 0; i < sliceRow->size(); i++) { + (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown, + 1.0f)); + } m_sliceDataArray << duplicateRow; @@ -540,8 +542,10 @@ void Surface3DRenderer::updateScene(Q3DScene *scene) Abstract3DRenderer::updateScene(scene); - if (m_selectionPointer) - m_selectionPointer->updateScene(m_cachedScene); + if (m_selectionPointer && m_selectionActive + && m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) { + m_selectionDirty = true; // Ball may need repositioning if scene changes + } updateSlicingActive(scene->isSlicingActive()); } @@ -557,7 +561,7 @@ void Surface3DRenderer::render(GLuint defaultFboHandle) // Render selection ball if (m_selectionPointer && m_selectionActive - && m_cachedSelectionMode.testFlag(QDataVis::SelectionItem)) { + && m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) { m_selectionPointer->render(defaultFboHandle); } } @@ -566,6 +570,8 @@ void Surface3DRenderer::drawSlicedScene() { QVector3D lightPos; + QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); + // Specify viewport glViewport(m_secondarySubViewport.x(), m_secondarySubViewport.y(), @@ -575,7 +581,8 @@ void Surface3DRenderer::drawSlicedScene() // Set up projection matrix QMatrix4x4 projectionMatrix; - GLfloat aspect = (GLfloat)m_secondarySubViewport.width() / (GLfloat)m_secondarySubViewport.height(); + GLfloat aspect = (GLfloat)m_secondarySubViewport.width() + / (GLfloat)m_secondarySubViewport.height(); projectionMatrix.ortho(-sliceUnits * aspect, sliceUnits * aspect, -sliceUnits, sliceUnits, -1.0f, 4.0f); @@ -588,7 +595,7 @@ void Surface3DRenderer::drawSlicedScene() QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; - bool rowMode = m_cachedSelectionMode.testFlag(QDataVis::SelectionRow); + bool rowMode = m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow); GLfloat scaleX = 0.0f; GLfloat scaleXBackground = 0.0f; @@ -608,6 +615,8 @@ void Surface3DRenderer::drawSlicedScene() QMatrix4x4 modelMatrix; QMatrix4x4 itModelMatrix; + const SeriesRenderCache &series = m_visibleSeriesList.at(0); + modelMatrix.translate(offset, 0.0f, 0.0f); QVector3D scaling(scaleX, 1.0f, sliceZScale); modelMatrix.scale(scaling); @@ -621,11 +630,12 @@ void Surface3DRenderer::drawSlicedScene() glPolygonOffset(0.5f, 1.0f); } - ShaderHelper *surfaceShader = m_shader; + ShaderHelper *surfaceShader = m_surfaceShader; surfaceShader->bind(); - QVector3D color; - color = Utils::vectorFromColor(m_cachedTheme->multiHighlightColor()); + GLuint baseGradientTexture = m_uniformGradientTexture; + if (series.colorStyle() != Q3DTheme::ColorStyleUniform) + baseGradientTexture = series.baseGradientTexture(); // Set shader bindings surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos); @@ -634,12 +644,12 @@ void Surface3DRenderer::drawSlicedScene() surfaceShader->setUniformValue(surfaceShader->nModel(), itModelMatrix.inverted().transposed()); surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix); - surfaceShader->setUniformValue(surfaceShader->color(), color); - surfaceShader->setUniformValue(surfaceShader->lightS(), 0.25f); + surfaceShader->setUniformValue(surfaceShader->lightS(), 0.15f); surfaceShader->setUniformValue(surfaceShader->ambientS(), - m_cachedTheme->ambientLightStrength() * 2.0f); + m_cachedTheme->ambientLightStrength() * 2.3f); + surfaceShader->setUniformValue(surfaceShader->lightColor(), lightColor); - m_drawer->drawObject(surfaceShader, m_sliceSurfaceObj); + m_drawer->drawObject(surfaceShader, m_sliceSurfaceObj, baseGradientTexture); } // Draw surface grid @@ -668,8 +678,10 @@ void Surface3DRenderer::drawSlicedScene() lineShader->setUniformValue(lineShader->lightP(), lightPos); lineShader->setUniformValue(lineShader->view(), viewMatrix); lineShader->setUniformValue(lineShader->color(), lineColor); - lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength() * 2.0f); - lineShader->setUniformValue(lineShader->lightS(), 0.25f); + lineShader->setUniformValue(lineShader->ambientS(), + m_cachedTheme->ambientLightStrength() * 2.3f); + lineShader->setUniformValue(lineShader->lightS(), 0.0f); + lineShader->setUniformValue(lineShader->lightColor(), lightColor); // Horizontal lines if (m_axisCacheY.segmentCount() > 0) { @@ -792,7 +804,7 @@ void Surface3DRenderer::drawSlicedScene() } labelNbr = 0; - positionComp.setY(backgroundMargin); + positionComp.setY(-0.1f); rotation.setZ(-45.0f); labelTrans.setY(-backgroundMargin); for (int segment = 0; segment <= lastSegment; segment++) { @@ -809,9 +821,9 @@ void Surface3DRenderer::drawSlicedScene() axisLabelItem = m_axisCacheZ.labelItems().at(labelNbr); m_drawer->drawLabel(m_dummyRenderItem, *axisLabelItem, viewMatrix, projectionMatrix, - positionComp, rotation, 0, QDataVis::SelectionRow, + positionComp, rotation, 0, QAbstract3DGraph::SelectionRow, m_labelShader, m_labelObj, m_cachedScene->activeCamera(), - false, false, Drawer::LabelBelow, Qt::AlignTop, true); + false, false, Drawer::LabelBelow, Qt::AlignBottom, true); } labelNbr++; labelPos += posStep; @@ -828,6 +840,8 @@ void Surface3DRenderer::drawSlicedScene() void Surface3DRenderer::drawScene(GLuint defaultFboHandle) { GLfloat backgroundRotation = 0; + QVector3D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); + glViewport(m_primarySubViewport.x(), m_primarySubViewport.y(), m_primarySubViewport.width(), @@ -877,12 +891,15 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Draw depth buffer #if !defined(QT_OPENGL_ES_2) GLfloat adjustedLightStrength = m_cachedTheme->lightStrength() / 10.0f; - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_surfaceObj && m_cachedSurfaceVisible) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone && m_surfaceObj + && m_cachedSurfaceVisible) { // Render scene into a depth texture for using with shadow mapping // Enable drawing to depth framebuffer glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer); + // Attach texture to depth attachment - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + m_depthTexture, 0); glClear(GL_DEPTH_BUFFER_BIT); // Bind depth shader @@ -899,9 +916,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) zeroVector, 0.0f, 3.5f / m_autoScaleAdjustment); depthViewMatrix.lookAt(depthLightPos, zeroVector, upVector); - // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? - // That causes the scene to be not drawn from above -> must be fixed - // qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3); // Set the depth projection matrix #ifndef USE_WIDER_SHADOWS // Use this for perspective shadows @@ -943,7 +957,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthModelTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + m_depthModelTexture, 0); glClear(GL_DEPTH_BUFFER_BIT); // Draw the triangles @@ -968,21 +983,6 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Reset culling to normal glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - -#if 0 // Use this if you want to see what is being drawn to the framebuffer - // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it) - { - m_labelShader->bind(); - glEnable(GL_TEXTURE_2D); - QMatrix4x4 modelMatrix; - QMatrix4x4 viewmatrix; - viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f), zeroVector, upVector); - QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix; - m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix); - m_drawer->drawObject(m_labelShader, m_labelObj, m_depthTexture); - glDisable(GL_TEXTURE_2D); - } -#endif } #endif // Enable texturing @@ -990,7 +990,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // Draw selection buffer if (!m_cachedIsSlicingActivated && m_surfaceObj && m_selectionState == SelectOnScene - && m_cachedSelectionMode > QDataVis::SelectionNone + && m_cachedSelectionMode > QAbstract3DGraph::SelectionNone && (m_cachedSurfaceVisible || m_cachedSurfaceGridOn) && m_visibleSeriesList.size() > 0) { m_selectionShader->bind(); @@ -1034,8 +1034,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) uint selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536; #endif - emit pointClicked(QPoint(selectionIdToSurfacePoint(selectionId)), - static_cast<QSurface3DSeries *>(m_visibleSeriesList.at(0).series())); + m_clickedPosition = selectionIdToSurfacePoint(selectionId); + m_clickedSeries = m_visibleSeriesList.at(0).series(); + + emit needRender(); // Revert to original viewport glViewport(m_primarySubViewport.x(), @@ -1078,8 +1080,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_surfaceShader->setUniformValue(m_surfaceShader->MVP(), MVPMatrix); m_surfaceShader->setUniformValue(m_surfaceShader->ambientS(), m_cachedTheme->ambientLightStrength()); + m_surfaceShader->setUniformValue(m_surfaceShader->lightColor(), lightColor); - // TODO: Do properly when multiseries support implemented QTRD-2657 GLuint gradientTexture; if (m_visibleSeriesList.at(0).colorStyle() == Q3DTheme::ColorStyleUniform) gradientTexture = m_uniformGradientTexture; @@ -1087,15 +1089,17 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) gradientTexture = m_visibleSeriesList.at(0).baseGradientTexture(); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - m_surfaceShader->setUniformValue(m_surfaceShader->shadowQ(), m_shadowQualityToShader); + m_surfaceShader->setUniformValue(m_surfaceShader->shadowQ(), + m_shadowQualityToShader); m_surfaceShader->setUniformValue(m_surfaceShader->depth(), depthMVPMatrix); m_surfaceShader->setUniformValue(m_surfaceShader->lightS(), adjustedLightStrength); // Draw the object - m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture, m_depthModelTexture); + m_drawer->drawObject(m_surfaceShader, m_surfaceObj, gradientTexture, + m_depthModelTexture); } else #endif { @@ -1162,9 +1166,10 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor); m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(), m_cachedTheme->ambientLightStrength() * 2.0f); + m_backgroundShader->setUniformValue(m_backgroundShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), @@ -1204,8 +1209,9 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->view(), viewMatrix); lineShader->setUniformValue(lineShader->color(), lineColor); lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme->ambientLightStrength()); + lineShader->setUniformValue(lineShader->lightColor(), lightColor); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadowed shader bindings lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader); lineShader->setUniformValue(lineShader->lightS(), @@ -1214,11 +1220,12 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) #endif { // Set shadowless shader bindings - lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme->lightStrength() / 2.5f); + lineShader->setUniformValue(lineShader->lightS(), + m_cachedTheme->lightStrength() / 2.5f); } - QQuaternion lineYRotation = QQuaternion(); - QQuaternion lineXRotation = QQuaternion(); + QQuaternion lineYRotation; + QQuaternion lineXRotation; if (m_xFlipped) lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f); @@ -1263,7 +1270,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1307,7 +1314,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1352,7 +1359,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1398,7 +1405,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1450,7 +1457,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1495,7 +1502,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { // Set shadow shader bindings QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); @@ -1688,7 +1695,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) glUseProgram(0); // Selection handling - if (m_selectionDirty) { + if (m_selectionDirty || m_selectionLabelDirty) { QPoint visiblePoint = Surface3DController::invalidSelectionPosition(); if (m_selectedPoint != Surface3DController::invalidSelectionPosition()) { int x = m_selectedPoint.x() - m_sampleSpace.y(); @@ -1699,14 +1706,13 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) } } - if (m_cachedSelectionMode == QDataVis::SelectionNone + if (m_cachedSelectionMode == QAbstract3DGraph::SelectionNone || visiblePoint == Surface3DController::invalidSelectionPosition()) { m_selectionActive = false; } else { - // TODO: Need separate selection ball for slice and main surface view QTRD-2515 if (m_cachedIsSlicingActivated) updateSliceDataModel(visiblePoint); - if (m_cachedSelectionMode.testFlag(QDataVis::SelectionItem)) + if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionItem)) surfacePointSelected(visiblePoint); m_selectionActive = true; } @@ -1809,17 +1815,10 @@ void Surface3DRenderer::calculateSceneScalingFactors() m_areaSize.setHeight(m_axisCacheZ.max() - m_axisCacheZ.min()); m_areaSize.setWidth(m_axisCacheX.max() - m_axisCacheX.min()); m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); -#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z m_scaleX = aspectRatio * m_areaSize.width() / m_scaleFactor; m_scaleZ = aspectRatio * m_areaSize.height() / m_scaleFactor; m_scaleXWithBackground = m_scaleX * backgroundMargin; m_scaleZWithBackground = m_scaleZ * backgroundMargin; -#else // ..and this if we want uniform scaling based on largest dimension - m_scaleX = aspectRatio / m_scaleFactor; - m_scaleZ = aspectRatio / m_scaleFactor; - m_scaleXWithBackground = aspectRatio * backgroundMargin; - m_scaleZWithBackground = aspectRatio * backgroundMargin; -#endif } bool Surface3DRenderer::updateFlatStatus(bool enable) @@ -1858,6 +1857,12 @@ void Surface3DRenderer::updateSelectedPoint(const QPoint &position, const QSurfa m_selectionDirty = true; } +void Surface3DRenderer::resetClickedStatus() +{ + m_clickedPosition = Surface3DController::invalidSelectionPosition(); + m_clickedSeries = 0; +} + void Surface3DRenderer::updateSurfaceGridStatus(bool enable) { m_cachedSurfaceGridOn = enable; @@ -1905,13 +1910,13 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point) QVector3D pos; if (m_cachedIsSlicingActivated) { - if (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow)) { + if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionRow)) { pos = m_sliceSurfaceObj->vertexAt(column, 0); pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f); pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f); m_selectionPointer->updateBoundingRect(m_secondarySubViewport); m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment); - } else if (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn)) { + } else if (m_cachedSelectionMode.testFlag(QAbstract3DGraph::SelectionColumn)) { pos = m_sliceSurfaceObj->vertexAt(row, 0); pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f); pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f); @@ -1928,10 +1933,10 @@ void Surface3DRenderer::surfacePointSelected(const QPoint &point) m_selectionPointer->setPosition(pos); m_selectionPointer->setLabel(createSelectionLabel(value, column, row)); - // TODO: Get pointer object from correct series once multiseries support implemented m_selectionPointer->setPointerObject(m_visibleSeriesList.at(0).object()); m_selectionPointer->setHighlightColor(m_visibleSeriesList.at(0).singleHighlightColor()); m_selectionPointer->updateScene(m_cachedScene); + m_selectionPointer->setRotation(m_visibleSeriesList.at(0).meshRotation()); } // Maps selection Id to surface point in data array @@ -1944,7 +1949,6 @@ QPoint Surface3DRenderer::selectionIdToSurfacePoint(uint id) QString Surface3DRenderer::createSelectionLabel(float value, int column, int row) { - // TODO: Get from correct series once multiple series supported QString labelText = m_visibleSeriesList[0].itemLabelFormat(); static const QString xTitleTag(QStringLiteral("@xTitle")); static const QString yTitleTag(QStringLiteral("@yTitle")); @@ -1952,6 +1956,7 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row static const QString xLabelTag(QStringLiteral("@xLabel")); static const QString yLabelTag(QStringLiteral("@yLabel")); static const QString zLabelTag(QStringLiteral("@zLabel")); + static const QString seriesNameTag(QStringLiteral("@seriesName")); labelText.replace(xTitleTag, m_axisCacheX.title()); labelText.replace(yTitleTag, m_axisCacheY.title()); @@ -1981,35 +1986,39 @@ QString Surface3DRenderer::createSelectionLabel(float value, int column, int row labelText.replace(zLabelTag, valueLabelText); } + labelText.replace(seriesNameTag, m_visibleSeriesList[0].name()); + + m_selectionLabelDirty = false; + return labelText; } -void Surface3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality) +void Surface3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality) { m_cachedShadowQuality = quality; switch (quality) { - case QDataVis::ShadowQualityLow: + case QAbstract3DGraph::ShadowQualityLow: m_shadowQualityToShader = 33.3f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualityMedium: + case QAbstract3DGraph::ShadowQualityMedium: m_shadowQualityToShader = 100.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualityHigh: + case QAbstract3DGraph::ShadowQualityHigh: m_shadowQualityToShader = 200.0f; m_shadowQualityMultiplier = 5; break; - case QDataVis::ShadowQualitySoftLow: + case QAbstract3DGraph::ShadowQualitySoftLow: m_shadowQualityToShader = 5.0f; m_shadowQualityMultiplier = 1; break; - case QDataVis::ShadowQualitySoftMedium: + case QAbstract3DGraph::ShadowQualitySoftMedium: m_shadowQualityToShader = 10.0f; m_shadowQualityMultiplier = 3; break; - case QDataVis::ShadowQualitySoftHigh: + case QAbstract3DGraph::ShadowQualitySoftHigh: m_shadowQualityToShader = 15.0f; m_shadowQualityMultiplier = 4; break; @@ -2058,18 +2067,15 @@ void Surface3DRenderer::loadLabelMesh() void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader) { - // m_shader is used slice view surface only. - if (m_shader) - delete m_shader; - m_shader = new ShaderHelper(this, vertexShader, fragmentShader); - m_shader->initialize(); + Q_UNUSED(vertexShader); + Q_UNUSED(fragmentShader); // draw the shader for the surface according to smooth status, shadow and uniform color if (m_surfaceShader) delete m_surfaceShader; #if !defined(QT_OPENGL_ES_2) if (!m_cachedFlatShading) { - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexShadow"), QStringLiteral(":/shaders/fragmentSurfaceShadowNoTex")); } else { @@ -2077,7 +2083,7 @@ void Surface3DRenderer::initShaders(const QString &vertexShader, const QString & QStringLiteral(":/shaders/fragmentSurface")); } } else { - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceShadowFlat"), QStringLiteral(":/shaders/fragmentSurfaceShadowFlat")); } else { @@ -2147,15 +2153,20 @@ void Surface3DRenderer::updateDepthBuffer() m_textureHelper->deleteTexture(&m_depthTexture); m_depthTexture = 0; } + if (m_depthModelTexture) { + m_textureHelper->deleteTexture(&m_depthModelTexture); + m_depthModelTexture = 0; + } if (m_primarySubViewport.size().isEmpty()) return; - if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) { + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { m_depthTexture = m_textureHelper->createDepthTextureFrameBuffer(m_primarySubViewport.size(), m_depthFrameBuffer, m_shadowQualityMultiplier); - m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(), m_shadowQualityMultiplier, 1.0f); + m_textureHelper->fillDepthTexture(m_depthTexture, m_primarySubViewport.size(), + m_shadowQualityMultiplier, 1.0f); m_depthModelTexture = m_textureHelper->createDepthTexture(m_primarySubViewport.size(), m_shadowQualityMultiplier); if (!m_depthTexture || !m_depthModelTexture) @@ -2167,7 +2178,6 @@ void Surface3DRenderer::updateDepthBuffer() void Surface3DRenderer::generateUniformGradient(const QVector3D newColor) { if (m_visibleSeriesList.size()) { - // TODO: move uniform gradient to render cache when multiseries support implemented QTRD-2657 QColor newQColor = Utils::colorFromVector(newColor); m_uniformGradientTextureColor = newColor; QLinearGradient newGradient; @@ -2177,4 +2187,4 @@ void Surface3DRenderer::generateUniformGradient(const QVector3D newColor) } } -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index f70fde9b..06973f43 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc +** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.digia.com ** @@ -29,28 +29,17 @@ #ifndef SURFACE3DRENDERER_P_H #define SURFACE3DRENDERER_P_H -#include <QtCore/QSize> -#include <QtCore/QObject> -#include <QtGui/QOpenGLFunctions> -#include <QtGui/QFont> -#include <QWindow> - #include "datavisualizationglobal_p.h" #include "surface3dcontroller_p.h" #include "abstract3drenderer_p.h" #include "scatterrenderitem_p.h" #include "qsurfacedataproxy.h" -class QOpenGLShaderProgram; - -QT_DATAVISUALIZATION_BEGIN_NAMESPACE +QT_BEGIN_NAMESPACE_DATAVISUALIZATION class ShaderHelper; class ObjectHelper; class SurfaceObject; -class TextureHelper; -class Theme; -class Drawer; class Q3DScene; class SelectionPointer; @@ -69,7 +58,6 @@ private: bool m_cachedIsSlicingActivated; // Internal attributes purely related to how the scene is drawn with GL. - ShaderHelper *m_shader; ShaderHelper *m_depthShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_surfaceShader; @@ -126,6 +114,7 @@ private: const QSurface3DSeries *m_selectedSeries; GLuint m_uniformGradientTexture; QVector3D m_uniformGradientTextureColor; + QPoint m_clickedPosition; public: explicit Surface3DRenderer(Surface3DController *controller); @@ -140,6 +129,8 @@ public: void updateSurfaceGridStatus(bool enable); void updateSlicingActive(bool isSlicing); void updateSelectedPoint(const QPoint &position, const QSurface3DSeries *series); + inline QPoint clickedPosition() const { return m_clickedPosition; } + void resetClickedStatus(); void drawSlicedScene(); void render(GLuint defaultFboHandle = 0); @@ -148,12 +139,11 @@ protected: void initializeOpenGL(); signals: - void pointClicked(QPoint position, QSurface3DSeries *series); void flatShadingSupportedChanged(bool supported); private: void updateSliceDataModel(const QPoint &point); - void updateShadowQuality(QDataVis::ShadowQuality quality); + void updateShadowQuality(QAbstract3DGraph::ShadowQuality quality); void updateTextures(); void initShaders(const QString &vertexShader, const QString &fragmentShader); QRect calculateSampleRect(const QSurfaceDataArray &array); @@ -185,6 +175,6 @@ private: Q_DISABLE_COPY(Surface3DRenderer) }; -QT_DATAVISUALIZATION_END_NAMESPACE +QT_END_NAMESPACE_DATAVISUALIZATION -#endif // SURFACE3DRENDERER_P_H +#endif |