From 92ee7767f81f7a15b8773ed97356f01ecac68d0c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 16 May 2014 15:26:14 +0300 Subject: Implement axis label autorotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-2857 Change-Id: I158abb75272813cf7eb5d4b419e24325389d940e Reviewed-by: Tomi Korpipää --- src/datavisualization/axis/qabstract3daxis.cpp | 38 +++- src/datavisualization/axis/qabstract3daxis.h | 5 + src/datavisualization/axis/qabstract3daxis_p.h | 1 + .../engine/abstract3dcontroller.cpp | 41 ++++ .../engine/abstract3dcontroller_p.h | 10 +- .../engine/abstract3drenderer.cpp | 8 + .../engine/abstract3drenderer_p.h | 2 + src/datavisualization/engine/axisrendercache.cpp | 3 +- src/datavisualization/engine/axisrendercache_p.h | 3 + src/datavisualization/engine/bars3drenderer.cpp | 206 +++++++++++++++--- src/datavisualization/engine/drawer.cpp | 61 ++---- src/datavisualization/engine/scatter3drenderer.cpp | 230 +++++++++++++++----- src/datavisualization/engine/surface3drenderer.cpp | 232 ++++++++++++++++----- 13 files changed, 656 insertions(+), 184 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/axis/qabstract3daxis.cpp b/src/datavisualization/axis/qabstract3daxis.cpp index ef4959d4..27951f4c 100644 --- a/src/datavisualization/axis/qabstract3daxis.cpp +++ b/src/datavisualization/axis/qabstract3daxis.cpp @@ -89,6 +89,15 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * If set, the axis will automatically adjust the range so that all data fits in it. */ +/*! + * \qmlproperty real AbstractAxis3D::labelAutoRotation + * + * Defines the maximum \a angle the labels can autorotate when the camera angle changes. + * The \a angle can be between 0 and 90, inclusive. The default value is 0. + * If the value is 0, axis labels do not automatically rotate. + * If the value is greater than zero, labels attempt to orient themselves toward the camera, up to + * the specified angle. + */ /*! * \enum QAbstract3DAxis::AxisOrientation @@ -193,6 +202,32 @@ void QAbstract3DAxis::setRange(float min, float max) setAutoAdjustRange(false); } +/*! + * \property QAbstract3DAxis::labelAutoRotation + * + * Defines the maximum \a angle the labels can autorotate when the camera angle changes. + * The \a angle can be between 0 and 90, inclusive. The default value is 0. + * If the value is 0, axis labels do not automatically rotate. + * If the value is greater than zero, labels attempt to orient themselves toward the camera, up to + * the specified angle. + */ +void QAbstract3DAxis::setLabelAutoRotation(float angle) +{ + if (angle < 0.0f) + angle = 0.0f; + if (angle > 90.0f) + angle = 90.0f; + if (d_ptr->m_labelAutoRotation != angle) { + d_ptr->m_labelAutoRotation = angle; + emit labelAutoRotationChanged(angle); + } +} + +float QAbstract3DAxis::labelAutoRotation() const +{ + return d_ptr->m_labelAutoRotation; +} + /*! * \property QAbstract3DAxis::min * @@ -266,7 +301,8 @@ QAbstract3DAxisPrivate::QAbstract3DAxisPrivate(QAbstract3DAxis *q, QAbstract3DAx m_isDefaultAxis(false), m_min(0.0f), m_max(10.0f), - m_autoAdjust(true) + m_autoAdjust(true), + m_labelAutoRotation(0.0f) { } diff --git a/src/datavisualization/axis/qabstract3daxis.h b/src/datavisualization/axis/qabstract3daxis.h index 2b2be229..286e87bd 100644 --- a/src/datavisualization/axis/qabstract3daxis.h +++ b/src/datavisualization/axis/qabstract3daxis.h @@ -40,6 +40,7 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DAxis : public QObject Q_PROPERTY(float min READ min WRITE setMin NOTIFY minChanged) Q_PROPERTY(float max READ max WRITE setMax NOTIFY maxChanged) Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged) + Q_PROPERTY(float labelAutoRotation READ labelAutoRotation WRITE setLabelAutoRotation NOTIFY labelAutoRotationChanged REVISION 1) public: enum AxisOrientation { @@ -81,6 +82,9 @@ public: void setRange(float min, float max); + void setLabelAutoRotation(float angle); + float labelAutoRotation() const; + signals: void titleChanged(const QString &newTitle); void labelsChanged(); @@ -89,6 +93,7 @@ signals: void maxChanged(float value); void rangeChanged(float min, float max); void autoAdjustRangeChanged(bool autoAdjust); + Q_REVISION(1) void labelAutoRotationChanged(float angle); protected: QScopedPointer d_ptr; diff --git a/src/datavisualization/axis/qabstract3daxis_p.h b/src/datavisualization/axis/qabstract3daxis_p.h index 38d5361c..eea3593c 100644 --- a/src/datavisualization/axis/qabstract3daxis_p.h +++ b/src/datavisualization/axis/qabstract3daxis_p.h @@ -67,6 +67,7 @@ protected: float m_min; float m_max; bool m_autoAdjust; + float m_labelAutoRotation; friend class QAbstract3DAxis; friend class QValue3DAxis; diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 98fff81e..9ba39786 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -392,6 +392,24 @@ void Abstract3DController::synchDataToRenderer() } } + if (m_changeTracker.axisXLabelAutoRotationChanged) { + m_renderer->updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientationX, + m_axisX->labelAutoRotation()); + m_changeTracker.axisXLabelAutoRotationChanged = false; + } + + if (m_changeTracker.axisYLabelAutoRotationChanged) { + m_renderer->updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientationY, + m_axisY->labelAutoRotation()); + m_changeTracker.axisYLabelAutoRotationChanged = false; + } + + if (m_changeTracker.axisZLabelAutoRotationChanged) { + m_renderer->updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientationZ, + m_axisZ->labelAutoRotation()); + m_changeTracker.axisZLabelAutoRotationChanged = false; + } + if (m_changedSeriesList.size()) { m_renderer->modifiedSeriesList(m_changedSeriesList); m_changedSeriesList.clear(); @@ -1068,6 +1086,12 @@ void Abstract3DController::handleAxisFormatterDirty() handleAxisFormatterDirtyBySender(sender()); } +void Abstract3DController::handleAxisLabelAutoRotationChanged(float angle) +{ + Q_UNUSED(angle) + handleAxisLabelAutoRotationChangedBySender(sender()); +} + void Abstract3DController::handleInputViewChanged(QAbstract3DInputHandler::InputView view) { // When in automatic slicing mode, input view change to primary disables slice mode @@ -1167,6 +1191,20 @@ void Abstract3DController::handleAxisFormatterDirtyBySender(QObject *sender) emitNeedRender(); } +void Abstract3DController::handleAxisLabelAutoRotationChangedBySender(QObject *sender) +{ + if (sender == m_axisX) + m_changeTracker.axisXLabelAutoRotationChanged = true; + else if (sender == m_axisY) + m_changeTracker.axisYLabelAutoRotationChanged = true; + else if (sender == m_axisZ) + m_changeTracker.axisZLabelAutoRotationChanged = true; + else + qWarning() << __FUNCTION__ << "invoked for invalid axis"; + + emitNeedRender(); +} + void Abstract3DController::handleSeriesVisibilityChangedBySender(QObject *sender) { QAbstract3DSeries *series = static_cast(sender); @@ -1223,6 +1261,8 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient this, &Abstract3DController::handleAxisRangeChanged); QObject::connect(axis, &QAbstract3DAxis::autoAdjustRangeChanged, this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); + QObject::connect(axis, &QAbstract3DAxis::labelAutoRotationChanged, + this, &Abstract3DController::handleAxisLabelAutoRotationChanged); if (orientation == QAbstract3DAxis::AxisOrientationX) m_changeTracker.axisXTypeChanged = true; @@ -1236,6 +1276,7 @@ void Abstract3DController::setAxisHelper(QAbstract3DAxis::AxisOrientation orient handleAxisRangeChangedBySender(axis); handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), axis->isAutoAdjustRange()); + handleAxisLabelAutoRotationChangedBySender(axis); if (axis->type() & QAbstract3DAxis::AxisTypeValue) { QValue3DAxis *valueAxis = static_cast(axis); diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index bd78b6fa..e1b266ce 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -83,6 +83,9 @@ struct Abstract3DChangeBitField { bool axisYFormatterChanged : 1; bool axisZFormatterChanged : 1; bool projectionChanged : 1; + bool axisXLabelAutoRotationChanged : 1; + bool axisYLabelAutoRotationChanged : 1; + bool axisZLabelAutoRotationChanged : 1; Abstract3DChangeBitField() : zoomLevelChanged(true), @@ -117,7 +120,10 @@ struct Abstract3DChangeBitField { axisXFormatterChanged(true), axisYFormatterChanged(true), axisZFormatterChanged(true), - projectionChanged(true) + projectionChanged(true), + axisXLabelAutoRotationChanged(true), + axisYLabelAutoRotationChanged(true), + axisZLabelAutoRotationChanged(true) { } }; @@ -276,6 +282,7 @@ public: virtual void handleAxisLabelFormatChangedBySender(QObject *sender); virtual void handleAxisReversedChangedBySender(QObject *sender); virtual void handleAxisFormatterDirtyBySender(QObject *sender); + virtual void handleAxisLabelAutoRotationChangedBySender(QObject *sender); virtual void handleSeriesVisibilityChangedBySender(QObject *sender); virtual void handlePendingClick() = 0; virtual void adjustAxisRanges() = 0; @@ -292,6 +299,7 @@ public slots: void handleAxisLabelFormatChanged(const QString &format); void handleAxisReversedChanged(bool enable); void handleAxisFormatterDirty(); + void handleAxisLabelAutoRotationChanged(float angle); void handleInputViewChanged(QAbstract3DInputHandler::InputView view); void handleInputPositionChanged(const QPoint &position); void handleSeriesVisibilityChanged(bool visible); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 06954165..a2181271 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -366,6 +366,14 @@ void Abstract3DRenderer::updateAxisFormatter(QAbstract3DAxis::AxisOrientation or cache->setDataDirty(true); } +void Abstract3DRenderer::updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation, + float angle) +{ + AxisRenderCache &cache = axisCacheForOrientation(orientation); + if (cache.labelAutoRotation() != angle) + cache.setLabelAutoRotation(angle); +} + void Abstract3DRenderer::modifiedSeriesList(const QVector &seriesList) { foreach (QAbstract3DSeries *series, seriesList) { diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 5cfb88ae..ebe473b9 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -108,6 +108,8 @@ public: bool enable); virtual void updateAxisFormatter(QAbstract3DAxis::AxisOrientation orientation, QValue3DAxisFormatter *formatter); + virtual void updateAxisLabelAutoRotation(QAbstract3DAxis::AxisOrientation orientation, + float angle); virtual void modifiedSeriesList(const QVector &seriesList); virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); diff --git a/src/datavisualization/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp index baa733b3..a90c9557 100644 --- a/src/datavisualization/engine/axisrendercache.cpp +++ b/src/datavisualization/engine/axisrendercache.cpp @@ -36,7 +36,8 @@ AxisRenderCache::AxisRenderCache() m_drawer(0), m_positionsDirty(true), m_translate(0.0f), - m_scale(1.0f) + m_scale(1.0f), + m_labelAutoRotation(0.0f) { } diff --git a/src/datavisualization/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h index 800421b1..c7f6574d 100644 --- a/src/datavisualization/engine/axisrendercache_p.h +++ b/src/datavisualization/engine/axisrendercache_p.h @@ -95,6 +95,8 @@ public: else return m_formatter->positionAt(value) * m_scale + m_translate; } + inline float labelAutoRotation() const { return m_labelAutoRotation; } + inline void setLabelAutoRotation(float angle) { m_labelAutoRotation = angle; } public slots: void updateTextures(); @@ -125,6 +127,7 @@ private: bool m_positionsDirty; float m_translate; float m_scale; + float m_labelAutoRotation; Q_DISABLE_COPY(AxisRenderCache) }; diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 459f8c25..537bb1ca 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -823,7 +823,7 @@ void Bars3DRenderer::drawSlicedScene() m_drawer->generateLabelItem(item.sliceLabelItem(), item.sliceLabel()); m_updateLabels = false; } - Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignBottom : Qt::AlignTop; + Qt::AlignmentFlag alignment = (item.height() < 0) ? Qt::AlignLeft : Qt::AlignRight; Drawer::LabelPosition labelPos = (item.height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver; m_dummyBarRenderItem.setTranslation(QVector3D(item.translation().x(), barPosYAdjustment - zeroPosAdjustment @@ -849,7 +849,7 @@ void Bars3DRenderer::drawSlicedScene() m_drawer->generateLabelItem(selectedItem->sliceLabelItem(), selectedItem->sliceLabel()); m_updateLabels = false; } - Qt::AlignmentFlag alignment = (selectedItem->height() < 0) ? Qt::AlignBottom : Qt::AlignTop; + Qt::AlignmentFlag alignment = (selectedItem->height() < 0) ? Qt::AlignLeft : Qt::AlignRight; Drawer::LabelPosition labelPos = (selectedItem->height() < 0) ? Drawer::LabelBelow : Drawer::LabelOver; m_dummyBarRenderItem.setTranslation(QVector3D(selectedItem->translation().x(), barPosYAdjustment - zeroPosAdjustment @@ -893,7 +893,7 @@ void Bars3DRenderer::drawSlicedScene() 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::LabelMid, Qt::AlignHCenter); + false, false, Drawer::LabelMid, Qt::AlignBottom); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); @@ -1879,6 +1879,11 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer glEnable(GL_POLYGON_OFFSET_FILL); + float labelAutoAngle = m_axisCacheY.labelAutoRotation(); + float labelAngleFraction = labelAutoAngle / 90.0f; + float fractionCamY = activeCamera->yRotation() * labelAngleFraction; + float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + // Y Labels int labelNbr = 0; int labelCount = m_axisCacheY.labelCount(); @@ -1888,20 +1893,42 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer GLfloat labelZTrans = columnScaleFactor; QVector3D backLabelRotation(0.0f, -90.0f, 0.0f); QVector3D sideLabelRotation(0.0f, 0.0f, 0.0f); - Qt::AlignmentFlag backAlignment = Qt::AlignLeft; - Qt::AlignmentFlag sideAlignment = Qt::AlignLeft; + Qt::AlignmentFlag backAlignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + Qt::AlignmentFlag sideAlignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + if (!m_xFlipped) { labelXTrans = -labelXTrans; labelMarginXTrans = -labelMargin; - backLabelRotation.setY(90.0f); - sideAlignment = Qt::AlignRight; } if (m_zFlipped) { labelZTrans = -labelZTrans; labelMarginZTrans = -labelMargin; - backAlignment = Qt::AlignRight; - sideLabelRotation.setY(180.f); } + + if (labelAutoAngle == 0.0f) { + if (!m_xFlipped) + backLabelRotation.setY(90.0f); + if (m_zFlipped) + sideLabelRotation.setY(180.f); + } else { + // Orient side labels somewhat towards the camera + if (m_xFlipped) { + if (m_zFlipped) + sideLabelRotation.setY(180.0f + (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(-90.0f + labelAutoAngle - fractionCamX); + } else { + if (m_zFlipped) + sideLabelRotation.setY(180.0f - (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(90.0f - labelAutoAngle - fractionCamX); + } + } + sideLabelRotation.setX(-fractionCamY); + backLabelRotation.setX(-fractionCamY); + QVector3D backLabelTrans = QVector3D(labelXTrans, 0.0f, labelZTrans + labelMarginZTrans); QVector3D sideLabelTrans = QVector3D(-labelXTrans - labelMarginXTrans, @@ -1941,6 +1968,10 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer // Z labels // Calculate the positions for row and column labels and store them + labelAutoAngle = m_axisCacheZ.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; GLfloat labelYAdjustment = 0.005f; GLfloat scaledRowWidth = rowScaleFactor; GLfloat scaledColumnDepth = columnScaleFactor; @@ -1948,18 +1979,70 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer GLfloat rowPosValue = scaledColumnDepth + labelMargin; GLfloat rowPos = 0.0f; GLfloat colPos = 0.0f; - QVector3D labelRotation(-90.0f, 0.0f, 0.0f); - if (m_zFlipped) - labelRotation.setY(180.0f); - if (m_yFlipped) { + Qt::AlignmentFlag alignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + QVector3D labelRotation; + + if (labelAutoAngle == 0.0f) { + labelRotation.setX(-90.0f); + if (m_zFlipped) + labelRotation.setY(180.0f); + if (m_yFlipped) { + if (m_zFlipped) + labelRotation.setY(0.0f); + else + labelRotation.setY(180.0f); + labelRotation.setZ(180.0f); + } + } else { if (m_zFlipped) - labelRotation.setY(0.0f); - else labelRotation.setY(180.0f); - labelRotation.setZ(180.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + (labelAutoAngle - fractionCamX) + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } + } } - Qt::AlignmentFlag alignment = m_xFlipped ? Qt::AlignLeft : Qt::AlignRight; 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 @@ -1991,19 +2074,76 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer false, drawSelection); } } - labelRotation = QVector3D(-90.0f, 90.0f, 0.0f); - if (m_xFlipped) - labelRotation.setY(-90.0f); - if (m_yFlipped) { + + // X labels + labelAutoAngle = m_axisCacheX.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; + alignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + if (labelAutoAngle == 0.0f) { + labelRotation = QVector3D(-90.0f, 90.0f, 0.0f); + if (m_xFlipped) + labelRotation.setY(-90.0f); + if (m_yFlipped) { + if (m_xFlipped) + labelRotation.setY(90.0f); + else + labelRotation.setY(-90.0f); + labelRotation.setZ(180.0f); + } + } else { if (m_xFlipped) - labelRotation.setY(90.0f); - else labelRotation.setY(-90.0f); - labelRotation.setZ(180.0f); + else + labelRotation.setY(90.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + fractionCamX + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f - fractionCamX + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - fractionCamX + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f + fractionCamX + * -(labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } + } } - // X labels - alignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft; 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 @@ -2036,6 +2176,20 @@ void Bars3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCamer } } +#if 0 // Debug label + static LabelItem debugLabelItem; + QString debugLabelString(QStringLiteral("Flips: x:%1 y:%2 z:%3")); + QString finalDebugString = debugLabelString.arg(m_xFlipped).arg(m_yFlipped).arg(m_zFlipped); + m_dummyBarRenderItem.setTranslation(QVector3D(m_xFlipped ? -1.5f : 1.5f, + m_yFlipped ? 1.5f : -1.5f, + m_zFlipped ? -1.5f : 1.5f)); + + m_drawer->generateLabelItem(debugLabelItem, finalDebugString); + m_drawer->drawLabel(m_dummyBarRenderItem, debugLabelItem, viewMatrix, projectionMatrix, + zeroVector, labelRotation, 0, m_cachedSelectionMode, + shader, m_labelObj, activeCamera, + true, false, Drawer::LabelMid, Qt::AlignHCenter, false, drawSelection); +#endif glDisable(GL_POLYGON_OFFSET_FILL); } diff --git a/src/datavisualization/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp index ff48d71c..0e336019 100644 --- a/src/datavisualization/engine/drawer.cpp +++ b/src/datavisualization/engine/drawer.cpp @@ -299,58 +299,22 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte 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()))); - } + QVector3D anchorPoint; switch (alignment) { case Qt::AlignLeft: { - 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; - } + anchorPoint.setX(float(-textureSize.width()) * scaleFactor); break; } case Qt::AlignRight: { - 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; - } + anchorPoint.setX(float(textureSize.width()) * scaleFactor); break; } case Qt::AlignTop: { - yAlignment = ((GLfloat)textureSize.width() * scaleFactor) * cosRotY; + anchorPoint.setY(float(-textureSize.height()) * scaleFactor); break; } case Qt::AlignBottom: { - 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; + anchorPoint.setY(float(textureSize.height()) * scaleFactor); break; } default: { @@ -367,15 +331,9 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte } // Position label - modelMatrix.translate(xPosition + xAlignment, yPosition + yAlignment, zPosition + zAlignment); + modelMatrix.translate(xPosition, yPosition, zPosition); // Rotate - QQuaternion rotQuatX = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, rotation.x()); - QQuaternion rotQuatY = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, rotation.y()); - QQuaternion rotQuatZ = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, rotation.z()); - QQuaternion rotQuaternion = rotQuatY * rotQuatZ * rotQuatX; - modelMatrix.rotate(rotQuaternion); - if (useDepth && !rotateAlong) { float yComp = float(qRadiansToDegrees(qTan(positionComp.y() / cameraDistance))); // Apply negative camera rotations to keep labels facing camera @@ -383,7 +341,14 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte float camRotationY = camera->yRotation(); modelMatrix.rotate(-camRotationX, 0.0f, 1.0f, 0.0f); modelMatrix.rotate(-camRotationY - yComp, 1.0f, 0.0f, 0.0f); + } else { + QQuaternion rotQuatX = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, rotation.x()); + QQuaternion rotQuatY = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, rotation.y()); + QQuaternion rotQuatZ = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, rotation.z()); + QQuaternion rotQuaternion = rotQuatY * rotQuatZ * rotQuatX; + modelMatrix.rotate(rotQuaternion); } + modelMatrix.translate(anchorPoint); // Scale label based on text size modelMatrix.scale(QVector3D((GLfloat)textureSize.width() * scaleFactor, diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 70fb7ed2..3fd8ece4 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -1349,6 +1349,11 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa glEnable(GL_POLYGON_OFFSET_FILL); + float labelAutoAngle = m_axisCacheZ.labelAutoRotation(); + float labelAngleFraction = labelAutoAngle / 90.0f; + float fractionCamY = activeCamera->yRotation() * labelAngleFraction; + float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + // Z Labels if (m_axisCacheZ.segmentCount() > 0) { int labelCount = m_axisCacheZ.labelCount(); @@ -1362,22 +1367,72 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa #endif int labelNbr = 0; GLfloat labelYTrans = -1.0f - m_backgroundMargin; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 0.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignRight; - if (m_zFlipped) - rotLabelY = 180.0f; - if (m_xFlipped) { + Qt::AlignmentFlag alignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + QVector3D labelRotation; + if (m_xFlipped) labelXTrans = -labelXTrans; - alignment = Qt::AlignLeft; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; + if (m_yFlipped) labelYTrans = -labelYTrans; + if (labelAutoAngle == 0.0f) { + labelRotation.setX(-90.0f); + if (m_zFlipped) + labelRotation.setY(180.0f); + if (m_yFlipped) { + if (m_zFlipped) + labelRotation.setY(0.0f); + else + labelRotation.setY(180.0f); + labelRotation.setZ(180.0f); + } + } else { + if (m_zFlipped) + labelRotation.setY(180.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + (labelAutoAngle - fractionCamX) + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } + } } - QVector3D labelRotateVector(rotLabelX, rotLabelY, rotLabelZ); QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, 0.0f); for (int label = 0; label < labelCount; label++) { if (m_axisCacheZ.labelItems().size() > labelNbr) { @@ -1396,7 +1451,7 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - zeroVector, labelRotateVector, 0, m_cachedSelectionMode, + zeroVector, labelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment); } @@ -1405,6 +1460,10 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } // X Labels if (m_axisCacheX.segmentCount() > 0) { + labelAutoAngle = m_axisCacheX.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; int labelCount = m_axisCacheX.labelCount(); #ifndef USE_UNIFORM_SCALING GLfloat labelZTrans = (aspectRatio * m_areaSize.height()) @@ -1416,22 +1475,75 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa #endif int labelNbr = 0; GLfloat labelYTrans = -1.0f - m_backgroundMargin; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignLeft; - if (m_xFlipped) - rotLabelY = -90.0f; - if (m_zFlipped) { + Qt::AlignmentFlag alignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + QVector3D labelRotation; + if (m_zFlipped) labelZTrans = -labelZTrans; - alignment = Qt::AlignRight; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; + if (m_yFlipped) labelYTrans = -labelYTrans; + if (labelAutoAngle == 0.0f) { + labelRotation = QVector3D(-90.0f, 90.0f, 0.0f); + if (m_xFlipped) + labelRotation.setY(-90.0f); + if (m_yFlipped) { + if (m_xFlipped) + labelRotation.setY(90.0f); + else + labelRotation.setY(-90.0f); + labelRotation.setZ(180.0f); + } + } else { + if (m_xFlipped) + labelRotation.setY(-90.0f); + else + labelRotation.setY(90.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + fractionCamX + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f - fractionCamX + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - fractionCamX + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f + fractionCamX + * -(labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } + } } - QVector3D labelRotateVector(rotLabelX, rotLabelY, rotLabelZ); + QVector3D labelTrans = QVector3D(0.0f, labelYTrans, labelZTrans); for (int label = 0; label < labelCount; label++) { if (m_axisCacheX.labelItems().size() > labelNbr) { @@ -1450,7 +1562,7 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - zeroVector, labelRotateVector, 0, m_cachedSelectionMode, + zeroVector, labelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment); } @@ -1459,6 +1571,10 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } // Y Labels if (m_axisCacheY.segmentCount() > 0) { + labelAutoAngle = m_axisCacheY.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; int labelCount = m_axisCacheY.labelCount(); int labelNbr = 0; #ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z @@ -1474,38 +1590,46 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa GLfloat labelXTrans = aspectRatio + m_backgroundMargin; GLfloat labelZTrans = labelXTrans; #endif - // Back wall init + // Back & side wall GLfloat labelMarginXTrans = labelMargin; GLfloat labelMarginZTrans = labelMargin; - GLfloat rotLabelX = 0.0f; - GLfloat rotLabelY = -90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignmentBack = Qt::AlignLeft; + QVector3D backLabelRotation(0.0f, -90.0f, 0.0f); + QVector3D sideLabelRotation(0.0f, 0.0f, 0.0f); + Qt::AlignmentFlag backAlignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + Qt::AlignmentFlag sideAlignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; if (!m_xFlipped) { labelXTrans = -labelXTrans; labelMarginXTrans = -labelMargin; - rotLabelY = 90.0f; } if (m_zFlipped) { labelZTrans = -labelZTrans; labelMarginZTrans = -labelMargin; - alignmentBack = Qt::AlignRight; } - QVector3D labelRotateVectorBack(rotLabelX, rotLabelY, rotLabelZ); - QVector3D labelTransBack = QVector3D(labelXTrans, 0.0f, labelZTrans + labelMarginZTrans); - - // Side wall init - Qt::AlignmentFlag alignmentSide = Qt::AlignLeft; - if (m_xFlipped) - alignmentSide = Qt::AlignLeft; - else - alignmentSide = Qt::AlignRight; - if (m_zFlipped) - rotLabelY = 180.0f; - else - rotLabelY = 0.0f; + if (labelAutoAngle == 0.0f) { + if (!m_xFlipped) + backLabelRotation.setY(90.0f); + if (m_zFlipped) + sideLabelRotation.setY(180.f); + } else { + // Orient side labels somewhat towards the camera + if (m_xFlipped) { + if (m_zFlipped) + sideLabelRotation.setY(180.0f + (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(-90.0f + labelAutoAngle - fractionCamX); + } else { + if (m_zFlipped) + sideLabelRotation.setY(180.0f - (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(90.0f - labelAutoAngle - fractionCamX); + } + } + sideLabelRotation.setX(-fractionCamY); + backLabelRotation.setX(-fractionCamY); - QVector3D labelRotateVectorSide(rotLabelX, rotLabelY, rotLabelZ); + QVector3D labelTransBack = QVector3D(labelXTrans, 0.0f, labelZTrans + labelMarginZTrans); QVector3D labelTransSide(-labelXTrans - labelMarginXTrans, 0.0f, -labelZTrans); for (int label = 0; label < labelCount; label++) { @@ -1525,17 +1649,17 @@ void Scatter3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa labelTransBack.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransBack); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - zeroVector, labelRotateVectorBack, 0, m_cachedSelectionMode, + zeroVector, backLabelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, alignmentBack); + Drawer::LabelMid, backAlignment); // Side wall labelTransSide.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransSide); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - zeroVector, labelRotateVectorSide, 0, m_cachedSelectionMode, + zeroVector, sideLabelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, - Drawer::LabelMid, alignmentSide); + Drawer::LabelMid, sideAlignment); } labelNbr++; } diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 30ffc381..b68a8087 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -1016,7 +1016,7 @@ void Surface3DRenderer::drawSlicedScene() m_drawer->drawLabel(m_dummyRenderItem, m_axisCacheY.titleItem(), viewMatrix, projectionMatrix, zeroVector, QVector3D(0.0f, 0.0f, 90.0f), 0, m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, - false, false, Drawer::LabelMid, Qt::AlignHCenter); + false, false, Drawer::LabelMid, Qt::AlignBottom); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); @@ -1836,6 +1836,11 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa glEnable(GL_POLYGON_OFFSET_FILL); + float labelAutoAngle = m_axisCacheZ.labelAutoRotation(); + float labelAngleFraction = labelAutoAngle / 90.0f; + float fractionCamY = activeCamera->yRotation() * labelAngleFraction; + float fractionCamX = activeCamera->xRotation() * labelAngleFraction; + // Z Labels QVector3D positionZComp(0.0f, 0.0f, 0.0f); if (m_axisCacheZ.segmentCount() > 0) { @@ -1843,25 +1848,76 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa int labelNbr = 0; GLfloat labelXTrans = m_scaleXWithBackground + labelMargin; GLfloat labelYTrans = -backgroundMargin; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 0.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignRight; - if (m_zFlipped) - rotLabelY = 180.0f; - if (m_xFlipped) { + Qt::AlignmentFlag alignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + QVector3D labelRotation; + if (m_xFlipped) labelXTrans = -labelXTrans; - alignment = Qt::AlignLeft; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; + if (m_yFlipped) labelYTrans = -labelYTrans; + if (labelAutoAngle == 0.0f) { + labelRotation.setX(-90.0f); + if (m_zFlipped) + labelRotation.setY(180.0f); + if (m_yFlipped) { + if (m_zFlipped) + labelRotation.setY(0.0f); + else + labelRotation.setY(180.0f); + labelRotation.setZ(180.0f); + } + } else { + if (m_zFlipped) + labelRotation.setY(180.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + (labelAutoAngle - fractionCamX) + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f - (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - (labelAutoAngle - fractionCamX) + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } + } } + QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, 0.0f); - QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); for (int label = 0; label < labelCount; label++) { if (m_axisCacheZ.labelItems().size() > labelNbr) { @@ -1878,7 +1934,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - positionZComp, rotation, 0, m_cachedSelectionMode, + positionZComp, labelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment); } @@ -1887,30 +1943,86 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } // X Labels if (m_axisCacheX.segmentCount() > 0) { + labelAutoAngle = m_axisCacheX.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; int labelCount = m_axisCacheX.labelCount(); int labelNbr = 0; GLfloat labelZTrans = m_scaleZWithBackground + labelMargin; GLfloat labelYTrans = -backgroundMargin; - GLfloat rotLabelX = -90.0f; - GLfloat rotLabelY = 90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignment = Qt::AlignLeft; - if (m_xFlipped) - rotLabelY = -90.0f; - if (m_zFlipped) { + Qt::AlignmentFlag alignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + QVector3D labelRotation; + if (m_zFlipped) labelZTrans = -labelZTrans; - alignment = Qt::AlignRight; - } - if (m_yFlipped) { - rotLabelZ += 180.0f; - rotLabelY += 180.0f; + if (m_yFlipped) labelYTrans = -labelYTrans; + if (labelAutoAngle == 0.0f) { + labelRotation = QVector3D(-90.0f, 90.0f, 0.0f); + if (m_xFlipped) + labelRotation.setY(-90.0f); + if (m_yFlipped) { + if (m_xFlipped) + labelRotation.setY(90.0f); + else + labelRotation.setY(-90.0f); + labelRotation.setZ(180.0f); + } + } else { + if (m_xFlipped) + labelRotation.setY(-90.0f); + else + labelRotation.setY(90.0f); + if (m_yFlipped) { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(90.0f - (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(90.0f + fractionCamX + * -(labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(90.0f - fractionCamX + * (-labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle - fractionCamY); + } + } + } else { + if (m_zFlipped) { + if (m_xFlipped) { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle - fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } else { + labelRotation.setX(-90.0f + (2.0f * labelAutoAngle + fractionCamX) + * (labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } + } else { + if (m_xFlipped) { + labelRotation.setX(-90.0f - fractionCamX + * (-labelAutoAngle + fractionCamY) / labelAutoAngle); + labelRotation.setZ(-labelAutoAngle + fractionCamY); + } else { + labelRotation.setX(-90.0f + fractionCamX + * -(labelAutoAngle - fractionCamY) / labelAutoAngle); + labelRotation.setZ(labelAutoAngle - fractionCamY); + } + } + } } QVector3D labelTrans = QVector3D(0.0f, labelYTrans, labelZTrans); - QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ); for (int label = 0; label < labelCount; label++) { if (m_axisCacheX.labelItems().size() > labelNbr) { @@ -1927,7 +2039,7 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - positionZComp, rotation, 0, m_cachedSelectionMode, + positionZComp, labelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, true, true, Drawer::LabelMid, alignment); } @@ -1936,44 +2048,56 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } // Y Labels if (m_axisCacheY.segmentCount() > 0) { + labelAutoAngle = m_axisCacheY.labelAutoRotation(); + labelAngleFraction = labelAutoAngle / 90.0f; + fractionCamY = activeCamera->yRotation() * labelAngleFraction; + fractionCamX = activeCamera->xRotation() * labelAngleFraction; int labelCount = m_axisCacheY.labelCount(); int labelNbr = 0; GLfloat labelXTrans = m_scaleXWithBackground; GLfloat labelZTrans = m_scaleZWithBackground; - // Back wall init + // Back & side wall GLfloat labelMarginXTrans = labelMargin; GLfloat labelMarginZTrans = labelMargin; - GLfloat rotLabelX = 0.0f; - GLfloat rotLabelY = -90.0f; - GLfloat rotLabelZ = 0.0f; - Qt::AlignmentFlag alignmentBack = Qt::AlignLeft; + QVector3D backLabelRotation(0.0f, -90.0f, 0.0f); + QVector3D sideLabelRotation(0.0f, 0.0f, 0.0f); + Qt::AlignmentFlag backAlignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; + Qt::AlignmentFlag sideAlignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; if (!m_xFlipped) { labelXTrans = -labelXTrans; labelMarginXTrans = -labelMargin; - rotLabelY = 90.0f; } if (m_zFlipped) { labelZTrans = -labelZTrans; labelMarginZTrans = -labelMargin; - alignmentBack = Qt::AlignRight; } - QVector3D labelRotateVectorBack(rotLabelX, rotLabelY, rotLabelZ); - QVector3D labelTransBack = QVector3D(labelXTrans, 0.0f, labelZTrans + labelMarginZTrans); - - // Side wall init - Qt::AlignmentFlag alignmentSide = Qt::AlignLeft; - if (m_xFlipped) - alignmentSide = Qt::AlignLeft; - else - alignmentSide = Qt::AlignRight; - if (m_zFlipped) - rotLabelY = 180.0f; - else - rotLabelY = 0.0f; + if (labelAutoAngle == 0.0f) { + if (!m_xFlipped) + backLabelRotation.setY(90.0f); + if (m_zFlipped) + sideLabelRotation.setY(180.f); + } else { + // Orient side labels somewhat towards the camera + if (m_xFlipped) { + if (m_zFlipped) + sideLabelRotation.setY(180.0f + (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(-90.0f + labelAutoAngle - fractionCamX); + } else { + if (m_zFlipped) + sideLabelRotation.setY(180.0f - (2.0f * labelAutoAngle) - fractionCamX); + else + sideLabelRotation.setY(-fractionCamX); + backLabelRotation.setY(90.0f - labelAutoAngle - fractionCamX); + } + } + sideLabelRotation.setX(-fractionCamY); + backLabelRotation.setX(-fractionCamY); - QVector3D labelRotateVectorSide(rotLabelX, rotLabelY, rotLabelZ); + QVector3D labelTransBack = QVector3D(labelXTrans, 0.0f, labelZTrans + labelMarginZTrans); QVector3D labelTransSide(-labelXTrans - labelMarginXTrans, 0.0f, -labelZTrans); for (int label = 0; label < labelCount; label++) { @@ -1993,17 +2117,17 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa labelTransBack.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransBack); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - positionZComp, labelRotateVectorBack, 0, m_cachedSelectionMode, + positionZComp, backLabelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, alignmentBack); + true, true, Drawer::LabelMid, backAlignment); // Side wall labelTransSide.setY(labelYTrans); m_dummyRenderItem.setTranslation(labelTransSide); m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix, - positionZComp, labelRotateVectorSide, 0, m_cachedSelectionMode, + positionZComp, sideLabelRotation, 0, m_cachedSelectionMode, shader, m_labelObj, activeCamera, - true, true, Drawer::LabelMid, alignmentSide); + true, true, Drawer::LabelMid, sideAlignment); } labelNbr++; } -- cgit v1.2.3