void CQ3DBarsModifier::zoomToSelectedBar() { m_animationCameraX.stop(); m_animationCameraY.stop(); m_animationCameraZoom.stop(); m_animationCameraTarget.stop(); Q3DCamera *camera = m_graph->scene()->activeCamera(); float currentX = camera->xRotation(); float currentY = camera->yRotation(); float currentZoom = camera->zoomLevel(); QVector3D currentTarget = camera->target(); m_animationCameraX.setStartValue(QVariant::fromValue(currentX)); m_animationCameraY.setStartValue(QVariant::fromValue(currentY)); m_animationCameraZoom.setStartValue(QVariant::fromValue(currentZoom)); m_animationCameraTarget.setStartValue(QVariant::fromValue(currentTarget)); QPoint selectedBar = m_graph->selectedSeries() ? m_graph->selectedSeries()->selectedBar() : QBar3DSeries::invalidSelectionPosition(); if (selectedBar != QBar3DSeries::invalidSelectionPosition()) { // Normalize selected bar position within axis range to determine target coordinates QVector3D endTarget; float xMin = m_graph->columnAxis()->min(); float xRange = m_graph->columnAxis()->max() - xMin; float zMin = m_graph->rowAxis()->min(); float zRange = m_graph->rowAxis()->max() - zMin; endTarget.setX((selectedBar.y() - xMin) / xRange * 2.0f - 1.0f); endTarget.setZ((selectedBar.x() - zMin) / zRange * 2.0f - 1.0f); // Rotate the camera so that it always points approximately to the graph center qreal endAngleX = 90.0 - qRadiansToDegrees(qAtan(qreal(endTarget.z() / endTarget.x()))); if (endTarget.x() > 0.0f) endAngleX -= 180.0f; float barValue = m_graph->selectedSeries()->dataProxy()->itemAt(selectedBar.x(), selectedBar.y())->value(); float endAngleY = barValue >= 0.0f ? 30.0f : -30.0f; if (m_graph->valueAxis()->reversed()) endAngleY *= -1.0f; m_animationCameraX.setEndValue(QVariant::fromValue(float(endAngleX))); m_animationCameraY.setEndValue(QVariant::fromValue(endAngleY)); m_animationCameraZoom.setEndValue(QVariant::fromValue(250)); m_animationCameraTarget.setEndValue(QVariant::fromValue(endTarget)); } else { // No selected bar, so return to the default view m_animationCameraX.setEndValue(QVariant::fromValue(m_defaultAngleX)); m_animationCameraY.setEndValue(QVariant::fromValue(m_defaultAngleY)); m_animationCameraZoom.setEndValue(QVariant::fromValue(m_defaultZoom)); m_animationCameraTarget.setEndValue(QVariant::fromValue(m_defaultTarget)); } m_animationCameraX.start(); m_animationCameraY.start(); m_animationCameraZoom.start(); m_animationCameraTarget.start(); }
void SelectionPointer::renderSelectionLabel(GLuint defaultFboHandle, bool useOrtho) { Q_UNUSED(defaultFboHandle) glViewport(m_mainViewPort.x(), m_mainViewPort.y(), m_mainViewPort.width(), m_mainViewPort.height()); Q3DCamera *camera = m_cachedScene->activeCamera(); // Get view matrix QMatrix4x4 viewMatrix; QMatrix4x4 modelMatrixLabel; QMatrix4x4 projectionMatrix; GLfloat viewPortRatio = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height(); if (m_cachedIsSlicingActivated) { GLfloat sliceUnitsScaled = sliceUnits / m_autoScaleAdjustment; viewMatrix.lookAt(QVector3D(0.0f, 0.0f, 1.0f), zeroVector, upVector); projectionMatrix.ortho(-sliceUnitsScaled * viewPortRatio, sliceUnitsScaled * viewPortRatio, -sliceUnitsScaled, sliceUnitsScaled, -1.0f, 4.0f); } else if (useOrtho) { viewMatrix = camera->d_ptr->viewMatrix(); GLfloat orthoRatio = 2.0f; projectionMatrix.ortho(-viewPortRatio * orthoRatio, viewPortRatio * orthoRatio, -orthoRatio, orthoRatio, 0.0f, 100.0f); } else { viewMatrix = camera->d_ptr->viewMatrix(); projectionMatrix.perspective(45.0f, viewPortRatio, 0.1f, 100.0f); } QSize textureSize = m_labelItem.size(); // Calculate scale factor to get uniform font size GLfloat scaledFontSize = 0.05f + m_drawer->font().pointSizeF() / 500.0f; GLfloat scaleFactor = scaledFontSize / (GLfloat)textureSize.height(); // Position label QVector3D labelAlign(0.0f, 1.0f * scaledFontSize + 0.05f, 0.0f); modelMatrixLabel.translate(m_position + labelAlign); // Position the label towards the camera float camRotationsX = camera->xRotation(); float camRotationsY = camera->yRotation(); if (!m_cachedIsSlicingActivated) { modelMatrixLabel.rotate(-camRotationsX, 0.0f, 1.0f, 0.0f); modelMatrixLabel.rotate(-camRotationsY, 1.0f, 0.0f, 0.0f); } // Scale label based on text size modelMatrixLabel.scale(QVector3D((GLfloat)textureSize.width() * scaleFactor, scaledFontSize, 0.0f)); // Make label to be always on top glDisable(GL_DEPTH_TEST); // Make label transparent glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_labelShader->bind(); QMatrix4x4 MVPMatrix; // Set shader bindings MVPMatrix = projectionMatrix * viewMatrix * modelMatrixLabel; m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix); // Draw the object m_drawer->drawObject(m_labelShader, m_labelObj, m_labelItem.textureId()); // Release shader glUseProgram(0); // Disable transparency glDisable(GL_BLEND); // Depth test back to normal glEnable(GL_DEPTH_TEST); }
CQ3DBarsModifier::CQ3DBarsModifier(CQArrayAnnotationsWidget* widget, Q3DBars *bargraph) : m_graph(bargraph), m_inputHandler(NULL), m_xRotation(0.0f), m_yRotation(0.0f), m_fontSize(30), m_segments(4), m_subSegments(3), m_minval(-1.0f), m_maxval(1.0f), m_valueAxis(new QValue3DAxis), m_rowAxis(new QCategory3DAxis), m_colAxis(new QCategory3DAxis), m_primarySeries(new QBar3DSeries), m_barMesh(QAbstract3DSeries::MeshBar), m_smooth(false) { m_graph->activeTheme()->setType(Q3DTheme::ThemeArmyBlue); m_graph->activeTheme()->setBackgroundEnabled(false); m_graph->activeTheme()->setLabelBackgroundEnabled(true); m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone); m_graph->setMultiSeriesUniform(true); m_valueAxis->setSegmentCount(m_segments); m_valueAxis->setSubSegmentCount(m_subSegments); m_valueAxis->setRange(m_minval, m_maxval); m_valueAxis->setLabelFormat(QString(QStringLiteral("%.1f "))); m_valueAxis->setLabelAutoRotation(30.0f); m_valueAxis->setTitleVisible(false); m_rowAxis->setLabelAutoRotation(30.0f); m_rowAxis->setTitleVisible(false); m_colAxis->setLabelAutoRotation(30.0f); m_colAxis->setTitleVisible(false); m_graph->setValueAxis(m_valueAxis); m_graph->setRowAxis(m_rowAxis); m_graph->setColumnAxis(m_colAxis); m_primarySeries->setItemLabelFormat(QStringLiteral("@rowLabel, @colLabel : @valueLabel")); m_primarySeries->setMesh(QAbstract3DSeries::MeshBar); m_primarySeries->setMeshSmooth(false); m_graph->addSeries(m_primarySeries); changePresetCamera(); clearData(); // Set up property animations for zooming to the selected bar Q3DCamera *camera = m_graph->scene()->activeCamera(); camera->setCameraPreset(Q3DCamera::CameraPresetIsometricRight); m_defaultAngleX = camera->xRotation(); m_defaultAngleY = camera->yRotation(); m_defaultZoom = camera->zoomLevel(); m_defaultTarget = camera->target(); m_animationCameraX.setTargetObject(camera); m_animationCameraY.setTargetObject(camera); m_animationCameraZoom.setTargetObject(camera); m_animationCameraTarget.setTargetObject(camera); m_animationCameraX.setPropertyName("xRotation"); m_animationCameraY.setPropertyName("yRotation"); m_animationCameraZoom.setPropertyName("zoomLevel"); m_animationCameraTarget.setPropertyName("target"); int duration = 1700; m_animationCameraX.setDuration(duration); m_animationCameraY.setDuration(duration); m_animationCameraZoom.setDuration(duration); m_animationCameraTarget.setDuration(duration); // The zoom always first zooms out above the graph and then zooms in qreal zoomOutFraction = 0.3; m_animationCameraX.setKeyValueAt(zoomOutFraction, QVariant::fromValue(0.0f)); m_animationCameraY.setKeyValueAt(zoomOutFraction, QVariant::fromValue(90.0f)); m_animationCameraZoom.setKeyValueAt(zoomOutFraction, QVariant::fromValue(50.0f)); m_animationCameraTarget.setKeyValueAt(zoomOutFraction, QVariant::fromValue(QVector3D(0.0f, 0.0f, 0.0f))); m_inputHandler = new CQCustomInputHandler(m_graph); m_inputHandler->setAxes(m_rowAxis, m_colAxis, m_valueAxis); m_graph->setActiveInputHandler(m_inputHandler); connect(m_inputHandler, SIGNAL(signalShowContextMenu(const QPoint &)), widget, SLOT(slotShowContextMenu(const QPoint&))); connect(m_inputHandler, SIGNAL(signalBarDoubleClicked(int, int)), widget, SLOT(selectTableCell(int, int))); }