summaryrefslogtreecommitdiffstats
path: root/src/datavis3d
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2013-04-30 13:50:57 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2013-05-02 07:34:26 +0300
commit984dc3069fc399178a234b3e740374f76af7ad04 (patch)
tree4788300d6a69f0ed10444d70d0c9d269f199a96d /src/datavis3d
parent82ebf1009002b3f73adf6c40fa221d618f7aace1 (diff)
Q3DMaps visualization type added
Very early draft. Also added early draft of an example using it. Change-Id: Ib6470607056748e979090ea0d9e751998ec1b3c9 Change-Id: Ib6470607056748e979090ea0d9e751998ec1b3c9 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavis3d')
-rw-r--r--src/datavis3d/engine/engine.pri3
-rw-r--r--src/datavis3d/engine/q3dbars.cpp5
-rw-r--r--src/datavis3d/engine/q3dmaps.cpp1246
-rw-r--r--src/datavis3d/engine/q3dmaps.h151
-rw-r--r--src/datavis3d/engine/q3dmaps_p.h165
-rw-r--r--src/datavis3d/engine/q3dwindow.h1
-rw-r--r--src/datavis3d/engine/qdataitem.cpp12
-rw-r--r--src/datavis3d/engine/qdataitem.h3
-rw-r--r--src/datavis3d/engine/qdataitem_p.h6
-rw-r--r--src/datavis3d/global/qdatavis3namespace.h10
10 files changed, 1585 insertions, 17 deletions
diff --git a/src/datavis3d/engine/engine.pri b/src/datavis3d/engine/engine.pri
index ab330803..ba063186 100644
--- a/src/datavis3d/engine/engine.pri
+++ b/src/datavis3d/engine/engine.pri
@@ -1,5 +1,6 @@
SOURCES += $$PWD/q3dwindow.cpp \
$$PWD/q3dbars.cpp \
+ $$PWD/q3dmaps.cpp \
$$PWD/qdataitem.cpp \
$$PWD/qdatarow.cpp \
$$PWD/qdataset.cpp \
@@ -11,6 +12,8 @@ HEADERS += $$PWD/q3dwindow_p.h \
$$PWD/q3dwindow.h \
$$PWD/q3dbars.h \
$$PWD/q3dbars_p.h \
+ $$PWD/q3dmaps.h \
+ $$PWD/q3dmaps_p.h \
$$PWD/qdataitem.h \
$$PWD/qdataitem_p.h \
$$PWD/qdatarow.h \
diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
index 241ffdc5..0b6dc60c 100644
--- a/src/datavis3d/engine/q3dbars.cpp
+++ b/src/datavis3d/engine/q3dbars.cpp
@@ -73,9 +73,6 @@ QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
//#define USE_HAX0R_SELECTION // keep this defined until the "real" method works
#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
-const GLfloat zComp = 10.0f; // Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly
-const QVector3D defaultLightPos = QVector3D(0.0f, 3.0f, zComp);
-const GLfloat defaultRatio = 1.0f / 1.6f; // default aspect ratio 16:10
const GLfloat gridLineWidth = 0.005f;
Q3DBars::Q3DBars()
@@ -656,7 +653,7 @@ void Q3DBars::drawScene()
d_ptr->m_selectedBar = item;
if (d_ptr->m_dataSet->d_ptr->rowLabelItems().size() > row
&& d_ptr->m_dataSet->d_ptr->columnLabelItems().size() > bar) {
- d_ptr->m_selectedBar->d_ptr->setPosition(
+ d_ptr->m_selectedBar->setPosition(
QPoint(d_ptr->m_dataSet->d_ptr->rowLabelItems().size()
- row - 1,
d_ptr->m_dataSet->d_ptr->columnLabelItems().size()
diff --git a/src/datavis3d/engine/q3dmaps.cpp b/src/datavis3d/engine/q3dmaps.cpp
new file mode 100644
index 00000000..516e3a25
--- /dev/null
+++ b/src/datavis3d/engine/q3dmaps.cpp
@@ -0,0 +1,1246 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "q3dmaps.h"
+#include "q3dmaps_p.h"
+#include "camerahelper_p.h"
+#include "qdataitem_p.h"
+#include "qdatarow_p.h"
+#include "qdataset_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+
+#include <QMatrix4x4>
+#include <QOpenGLPaintDevice>
+#include <QPainter>
+#include <QScreen>
+#include <QMouseEvent>
+
+#include <qmath.h>
+
+#include <QDebug>
+
+//#define DISPLAY_RENDER_SPEED
+
+#ifdef DISPLAY_RENDER_SPEED
+#include <QTime>
+#endif
+
+QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
+
+#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+
+const GLfloat gridLineWidth = 0.005f;
+
+Q3DMaps::Q3DMaps()
+ : d_ptr(new Q3DMapsPrivate(this))
+{
+}
+
+Q3DMaps::~Q3DMaps()
+{
+}
+
+void Q3DMaps::initialize()
+{
+ // Initialize shaders
+ if (!d_ptr->m_theme->m_uniformColor) {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"),
+ QStringLiteral(":/shaders/fragmentTexture"));
+ d_ptr->initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+ d_ptr->initSelectionShader();
+
+ // Init the selection buffer
+ d_ptr->initSelectionBuffer();
+
+ // Load default mesh
+ d_ptr->loadBarMesh();
+
+ // Load background mesh
+ d_ptr->loadBackgroundMesh();
+
+ // Load grid line mesh
+ d_ptr->loadGridLineMesh();
+
+ // Load label mesh
+ d_ptr->loadLabelMesh();
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+ // Set initial camera position
+ // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
+ CameraHelper::setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 20.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+
+ // Set view port
+ glViewport(0, 0, width(), height());
+
+ // Set initialized -flag
+ d_ptr->m_isInitialized = true;
+}
+
+void Q3DMaps::render()
+{
+ if (!d_ptr->m_isInitialized)
+ return;
+
+#ifdef DISPLAY_RENDER_SPEED
+ // For speed computation
+ static bool firstRender = true;
+ static QTime lastTime;
+ static GLint nbFrames = 0;
+ if (firstRender) {
+ lastTime.start();
+ firstRender = false;
+ }
+
+ // Measure speed (as milliseconds per frame)
+ nbFrames++;
+ if (lastTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
+ qDebug() << qreal(lastTime.elapsed()) / qreal(nbFrames) << "ms/frame (=" << qreal(nbFrames) << "fps)";
+ nbFrames = 0;
+ lastTime.restart();
+ }
+#endif
+
+ // If zoom selection is on, draw zoom scene
+ //drawZoomScene();
+ // Draw bars scene
+ drawScene();
+}
+
+void Q3DMaps::drawScene()
+{
+ // Set clear color
+ QVector3D clearColor = Utils::vectorFromColor(d_ptr->m_theme->m_windowColor);
+ glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ static QVector3D selection = QVector3D(0, 0, 0);
+
+ // Specify viewport
+ glViewport(d_ptr->m_sceneViewPort.x(), d_ptr->m_sceneViewPort.y(),
+ d_ptr->m_sceneViewPort.width(), d_ptr->m_sceneViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)d_ptr->m_sceneViewPort.width()
+ / (GLfloat)d_ptr->m_sceneViewPort.height(), 0.1f, 100.0f);
+
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(d_ptr->m_mousePos,
+ d_ptr->m_zoomLevel
+ * d_ptr->m_zoomAdjustment,
+ d_ptr->m_sceneViewPort.width(),
+ d_ptr->m_sceneViewPort.height());
+
+ // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ QVector3D lightPos = CameraHelper::calculateLightPosition(defaultLightPos);
+ //lightPos = QVector3D(0.0f, 4.0f, zComp); // center of bars, 4.0f above - for testing
+
+ // Skip selection mode drawing if we're zoomed or have no selection mode
+ if (!d_ptr->m_zoomActivated && d_ptr->m_selectionMode > ModeNone) {
+ // Bind selection shader
+ d_ptr->m_selectionShader->bind();
+
+ // Draw bars to selection buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, d_ptr->m_selectionFrameBuffer);
+ 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
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
+ glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
+ for (int bar = 0; bar < d_ptr->m_data->d_ptr->row().size(); bar++) {
+ QDataItem *item = d_ptr->m_data->d_ptr->getItem(bar);
+ if (!item)
+ continue;
+
+ GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer;
+
+ if (barHeight < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item->d_ptr->translation().x() / d_ptr->m_scaleFactor,
+ barHeight - d_ptr->m_yAdjustment,
+ item->d_ptr->translation().z() / d_ptr->m_scaleFactor
+ + zComp);
+ // TODO: Scale to whatever dimension was set as the expanding one
+ modelMatrix.scale(QVector3D(d_ptr->m_barThickness.x(), barHeight,
+ d_ptr->m_barThickness.z()));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // add +2 to avoid black
+ QVector3D barColor = QVector3D(1.0f - ((GLdouble)(bar + 2)
+ / (GLdouble)(d_ptr->m_data->d_ptr->row().size() + 2)),
+ (GLdouble)(bar + 2)
+ / (GLdouble)(d_ptr->m_data->d_ptr->row().size() + 2),
+ 0.0);
+
+ d_ptr->m_selectionShader->setUniformValue(d_ptr->m_selectionShader->MVP(),
+ MVPMatrix);
+ d_ptr->m_selectionShader->setUniformValue(d_ptr->m_selectionShader->color(),
+ barColor);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(d_ptr->m_selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_barObj->vertexBuf());
+ glVertexAttribPointer(d_ptr->m_selectionShader->posAtt(),
+ 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_barObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, d_ptr->m_barObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void*)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(d_ptr->m_selectionShader->posAtt());
+ }
+ glEnable(GL_DITHER);
+
+ // Read color under cursor
+ if (Q3DMapsPrivate::MouseOnScene == d_ptr->m_mousePressed)
+ selection = Utils::getSelection(d_ptr->m_mousePos, height());
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // Release selection shader
+ d_ptr->m_selectionShader->release();
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ glCullFace(GL_BACK);
+ d_ptr->m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ d_ptr->m_labelShader->setUniformValue(d_ptr->m_labelShader->MVP(), MVPMatrix);
+ d_ptr->m_drawer->drawObject(d_ptr->m_labelShader, d_ptr->m_labelObj, true,
+ d_ptr->m_selectionTexture);
+ glDisable(GL_TEXTURE_2D);
+ d_ptr->m_labelShader->release();
+#endif
+ }
+#if 1
+ // Bind bar shader
+ d_ptr->m_barShader->bind();
+
+ // Draw bars
+ // TODO: Handle zoom by camera transformations
+ //if (!d_ptr->m_zoomActivated)
+
+ bool barSelectionFound = false;
+ for (int bar = 0; bar < d_ptr->m_data->d_ptr->row().size(); bar++) {
+ QDataItem *item = d_ptr->m_data->d_ptr->getItem(bar);
+ if (!item)
+ continue;
+
+ GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer;
+
+ if (barHeight < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item->d_ptr->translation().x() / d_ptr->m_scaleFactor,
+ barHeight - d_ptr->m_yAdjustment,
+ item->d_ptr->translation().z() / d_ptr->m_scaleFactor
+ + zComp);
+ // TODO: Scale to whatever dimension was set as the expanding one
+ modelMatrix.scale(QVector3D(d_ptr->m_barThickness.x(), barHeight,
+ d_ptr->m_barThickness.z()));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(d_ptr->m_theme->m_baseColor);
+ QVector3D heightColor = Utils::vectorFromColor(d_ptr->m_theme->m_heightColor)
+ * barHeight;
+
+ QVector3D barColor = baseColor + heightColor;
+
+ GLfloat lightStrength = d_ptr->m_theme->m_lightStrength;
+ if (d_ptr->m_selectionMode > ModeNone) {
+ Q3DMapsPrivate::SelectionType selectionType = d_ptr->isSelected(bar, selection);
+ switch (selectionType) {
+ case Q3DMapsPrivate::SelectionBar: {
+ barColor = Utils::vectorFromColor(d_ptr->m_theme->m_highlightBarColor);
+ lightStrength = d_ptr->m_theme->m_highlightLightStrength;
+ // Insert data to QDataItem. We have no ownership, don't delete the previous one
+ if (!d_ptr->m_zoomActivated) {
+ d_ptr->m_selectedBar = item;
+ barSelectionFound = true;
+ }
+ break;
+ }
+ case Q3DMapsPrivate::SelectionNone: {
+ // Current bar is not selected, nor on a row or column
+ // do nothing
+ break;
+ }
+ default: {
+ // Unsupported selection mode
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ if (barHeight != 0) {
+ // Set shader bindings
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightP(), lightPos);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->view(), viewMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->color(), barColor);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightS(), lightStrength);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->ambientS(),
+ d_ptr->m_theme->m_ambientStrength);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_barObj);
+ }
+ }
+
+ // Release bar shader
+ d_ptr->m_barShader->release();
+#if 1
+ // Bind background shader
+ d_ptr->m_backgroundShader->bind();
+
+ // Enable texture
+ glEnable(GL_TEXTURE_2D);
+ glCullFace(GL_BACK);
+
+ // Draw background
+ if (d_ptr->m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - d_ptr->m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(d_ptr->m_areaSize.width() / d_ptr->m_scaleFactor,
+ 1.0f,
+ d_ptr->m_areaSize.height() / d_ptr->m_scaleFactor));
+ modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ QVector3D backgroundColor = Utils::vectorFromColor(d_ptr->m_theme->m_backgroundColor);
+
+ // Set shader bindings
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->lightP(),
+ lightPos);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->view(),
+ viewMatrix);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->model(),
+ modelMatrix);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->MVP(),
+ MVPMatrix);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->color(),
+ backgroundColor);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->lightS(),
+ d_ptr->m_theme->m_lightStrength);
+ d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->ambientS(),
+ d_ptr->m_theme->m_ambientStrength);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_backgroundShader, d_ptr->m_backgroundObj, true,
+ d_ptr->m_bgrTexture);
+ }
+
+ // Disable textures
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ // Release background shader
+ d_ptr->m_backgroundShader->release();
+#endif
+ // Draw grid lines
+#if 0
+ if (d_ptr->m_gridEnabled) {
+ // Bind bar shader
+ d_ptr->m_barShader->bind();
+
+ // Set unchanging shader bindings
+ QVector3D barColor = Utils::vectorFromColor(Qt::black);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightP(), lightPos);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->view(), viewMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->color(), barColor);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightS(),
+ d_ptr->m_theme->m_lightStrength);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->ambientS(),
+ d_ptr->m_theme->m_ambientStrength);
+
+ // Floor lines: rows
+ for (GLfloat row = 0.0f; row <= d_ptr->m_sampleCount.second; row++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ rowPos = (row + 0.5f) * (d_ptr->m_barSpacing.height());
+ modelMatrix.translate(0.0f, -d_ptr->m_yAdjustment,
+ (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(d_ptr->m_rowWidth / d_ptr->m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_gridLineObj);
+ }
+
+ // Floor lines: columns
+ for (GLfloat bar = 0.0f; bar <= d_ptr->m_sampleCount.first; bar++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ barPos = (bar + 0.5f) * (d_ptr->m_barSpacing.width());
+ modelMatrix.translate((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactor,
+ -d_ptr->m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ d_ptr->m_columnDepth / d_ptr->m_scaleFactor));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_gridLineObj);
+ }
+
+ // Wall lines: back wall
+ GLfloat heightStep = d_ptr->m_heightNormalizer / 2.5; // TODO: Replace 2.5 with a dynamic number deduced from scene?
+ for (GLfloat barHeight = heightStep; barHeight <= d_ptr->m_heightNormalizer * 2.0f;
+ barHeight += heightStep) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ if (d_ptr->m_zFlipped) {
+ modelMatrix.translate(0.0f,
+ barHeight / d_ptr->m_heightNormalizer - d_ptr->m_yAdjustment,
+ d_ptr->m_columnDepth / d_ptr->m_scaleFactor + zComp);
+ } else {
+ modelMatrix.translate(0.0f,
+ barHeight / d_ptr->m_heightNormalizer - d_ptr->m_yAdjustment,
+ -d_ptr->m_columnDepth / d_ptr->m_scaleFactor + zComp);
+ }
+ modelMatrix.scale(QVector3D(d_ptr->m_rowWidth / d_ptr->m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_gridLineObj);
+ }
+
+ // Wall lines: side wall
+ for (GLfloat barHeight = heightStep; barHeight <= d_ptr->m_heightNormalizer * 2.0f;
+ barHeight += heightStep) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ if (d_ptr->m_xFlipped) {
+ modelMatrix.translate(d_ptr->m_rowWidth / d_ptr->m_scaleFactor,
+ barHeight / d_ptr->m_heightNormalizer - d_ptr->m_yAdjustment,
+ zComp);
+ } else {
+ modelMatrix.translate(-d_ptr->m_rowWidth / d_ptr->m_scaleFactor,
+ barHeight / d_ptr->m_heightNormalizer - d_ptr->m_yAdjustment,
+ zComp);
+ }
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ d_ptr->m_columnDepth / d_ptr->m_scaleFactor));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
+ modelMatrix.inverted().transposed());
+ d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_gridLineObj);
+ }
+
+ // Release bar shader
+ d_ptr->m_barShader->release();
+ }
+#endif
+
+ // Handle zoom activation and label drawing
+ if (!barSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ d_ptr->m_selectedBar = NULL;
+ if (d_ptr->m_zoomActivated && Q3DMapsPrivate::MouseOnOverview == d_ptr->m_mousePressed) {
+ d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
+ d_ptr->m_zoomActivated = false;
+ }
+ } /*else if (d_ptr->m_selectionMode >= ModeZoomRow
+ && Q3DMapsPrivate::MouseOnScene == d_ptr->m_mousePressed) {
+ // Activate zoom mode
+ d_ptr->m_zoomActivated = true;
+ d_ptr->m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
+
+ // Create label textures
+ for (int col = 0; col < d_ptr->m_zoomSelection->d_ptr->row().size(); col++) {
+ QDataItem *item = d_ptr->m_zoomSelection->d_ptr->getItem(col);
+ d_ptr->m_drawer->generateLabelTexture(item);
+ }
+ }*/ else {
+ // Print value of selected bar
+ static QDataItem *prevItem = d_ptr->m_selectedBar;
+ d_ptr->m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ if (d_ptr->m_labelTransparency > TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+#ifndef DISPLAY_FULL_DATA_ON_SELECTION
+ // Draw just the value string of the selected bar
+ if (prevItem != d_ptr->m_selectedBar || m_updateLabels) {
+ d_ptr->m_drawer->generateLabelTexture(d_ptr->m_selectedBar);
+ prevItem = d_ptr->m_selectedBar;
+ }
+
+ d_ptr->m_drawer->drawLabel(*d_ptr->m_selectedBar, d_ptr->m_selectedBar->d_ptr->label(),
+ viewMatrix, projectionMatrix,
+ QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), d_ptr->m_heightNormalizer,
+ d_ptr->m_font, d_ptr->m_selectionMode, d_ptr->m_labelShader,
+ d_ptr->m_labelObj, true);
+#else
+ static bool firstSelection = true;
+ // Draw the value string followed by row label and column label
+ LabelItem labelItem = d_ptr->m_selectedBar->d_ptr->selectionLabel();
+ if (firstSelection || prevItem != d_ptr->m_selectedBar || d_ptr->m_updateLabels) {
+ QString labelText = d_ptr->m_selectedBar->d_ptr->valueStr();
+// if ((d_ptr->m_data->d_ptr->columnLabels().size()
+// > d_ptr->m_selectedBar->d_ptr->position().y())
+// && (d_ptr->m_data->d_ptr->rowLabels().size()
+// > d_ptr->m_selectedBar->d_ptr->position().x())) {
+// labelText.append(QStringLiteral(" ("));
+// labelText.append(d_ptr->m_data->d_ptr->rowLabels().at(
+// d_ptr->m_selectedBar->d_ptr->position().x()));
+// labelText.append(QStringLiteral(", "));
+// labelText.append(d_ptr->m_data->d_ptr->columnLabels().at(
+// d_ptr->m_selectedBar->d_ptr->position().y()));
+// labelText.append(QStringLiteral(")"));
+// //qDebug() << labelText;
+// }
+ d_ptr->m_drawer->generateLabelItem(&labelItem, labelText);
+ d_ptr->m_selectedBar->d_ptr->setSelectionLabel(labelItem);
+ prevItem = d_ptr->m_selectedBar;
+ firstSelection = false;
+ }
+
+ d_ptr->m_drawer->drawLabel(*d_ptr->m_selectedBar, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), d_ptr->m_heightNormalizer,
+ d_ptr->m_selectionMode, d_ptr->m_labelShader,
+ d_ptr->m_labelObj, true, false);
+#endif
+ glDisable(GL_TEXTURE_2D);
+ if (d_ptr->m_labelTransparency > TransparencyNone)
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ // Release label shader
+ d_ptr->m_labelShader->release();
+
+ // Reset label update flag; they should have been updated when we get here
+ d_ptr->m_updateLabels = false;
+ }
+#if 0
+ // TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
+ // Bind label shader
+ d_ptr->m_labelShader->bind();
+
+ glEnable(GL_TEXTURE_2D);
+ if (d_ptr->m_labelTransparency > TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Calculate the positions for row and column labels and store them into QDataItems (and QDataRows?)
+ for (int row = 0; row != d_ptr->m_sampleCount.second; row += 1) {
+ // 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 QDataSet. Just add LabelItems
+ rowPos = (row + 1) * (d_ptr->m_barSpacing.height());
+ barPos = 0;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignRight;
+ if (d_ptr->m_zFlipped)
+ rotLabelY = 180.0f;
+ if (d_ptr->m_xFlipped) {
+ barPos = (d_ptr->m_sampleCount.first + 1) * (d_ptr->m_barSpacing.width());
+ alignment = Qt::AlignLeft;
+ }
+ QVector3D labelPos = QVector3D((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactor,
+ -d_ptr->m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactor
+ + zComp);
+
+ // TODO: Try it; draw the label here
+
+ // Create a data item
+ QDataItem *label = new QDataItem();
+ label->d_ptr->setTranslation(labelPos);
+ if (d_ptr->m_data->d_ptr->rowLabelItems().size() > row) {
+ label->d_ptr->setLabel(d_ptr->m_data->d_ptr->rowLabelItems().at(
+ d_ptr->m_data->d_ptr->rowLabelItems().size() - row - 1));
+ }
+
+ //qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << d_ptr->m_dataSet->d_ptr->rowLabels().at(row);
+
+ d_ptr->m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, 0.0f), d_ptr->m_heightNormalizer,
+ d_ptr->m_selectionMode, d_ptr->m_labelShader,
+ d_ptr->m_labelObj, true, true, LabelMid, alignment);
+
+ delete label;
+ }
+ for (int bar = 0; bar != d_ptr->m_sampleCount.first; bar += 1) {
+ // 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 QDataSet. Just add LabelItems
+ barPos = (bar + 1) * (d_ptr->m_barSpacing.width());
+ rowPos = 0;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 90.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (d_ptr->m_xFlipped)
+ rotLabelY = -90.0f;
+ if (d_ptr->m_zFlipped) {
+ rowPos = (d_ptr->m_sampleCount.second + 1) * (d_ptr->m_barSpacing.height());
+ alignment = Qt::AlignRight;
+ }
+ QVector3D labelPos = QVector3D((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactor,
+ -d_ptr->m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactor
+ + zComp);
+
+ // TODO: Try it; draw the label here
+
+ // Create a data item
+ QDataItem *label = new QDataItem();
+ label->d_ptr->setTranslation(labelPos);
+ if (d_ptr->m_data->d_ptr->columnLabelItems().size() > bar) {
+ label->d_ptr->setLabel(d_ptr->m_data->d_ptr->columnLabelItems().at(
+ d_ptr->m_data->d_ptr->columnLabelItems().size()
+ - bar - 1));
+ }
+
+ //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << d_ptr->m_dataSet->d_ptr->columnLabels().at(bar);
+
+ d_ptr->m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, 0.0f), d_ptr->m_heightNormalizer,
+ d_ptr->m_selectionMode, d_ptr->m_labelShader,
+ d_ptr->m_labelObj, true, true, LabelMid, alignment);
+
+ delete label;
+ }
+ glDisable(GL_TEXTURE_2D);
+ if (d_ptr->m_labelTransparency > TransparencyNone)
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ d_ptr->m_labelShader->release();
+#endif
+#endif
+}
+
+void Q3DMaps::mousePressEvent(QMouseEvent *event)
+{
+ if (Qt::LeftButton == event->button()) {
+ if (d_ptr->m_zoomActivated) {
+ //qDebug() << event->pos().x() << event->pos().y() << d_ptr->m_sceneViewPort << d_ptr->m_zoomViewPort;
+ if (event->pos().x() <= d_ptr->m_sceneViewPort.width()
+ && event->pos().y() <= d_ptr->m_sceneViewPort.height()) {
+ d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnOverview;
+ //qDebug() << "Mouse pressed on overview";
+ } else {
+ d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnZoom;
+ //qDebug() << "Mouse pressed on zoom";
+ }
+ } else {
+ d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnScene;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ d_ptr->m_mousePos = event->pos();
+ //qDebug() << "Mouse pressed on scene";
+ }
+ } else if (Qt::MiddleButton == event->button()) {
+ // reset rotations
+ d_ptr->m_mousePos = QPoint(0, 0);
+ } else if (Qt::RightButton == event->button()) {
+ d_ptr->m_mousePressed = Q3DMapsPrivate::MouseRotating;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ d_ptr->m_mousePos = event->pos();
+ }
+ CameraHelper::updateMousePos(d_ptr->m_mousePos);
+}
+
+void Q3DMaps::mouseReleaseEvent(QMouseEvent *event)
+{
+ //qDebug() << "mouse button released" << event->button();
+ if (Q3DMapsPrivate::MouseRotating == d_ptr->m_mousePressed) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ d_ptr->m_mousePos = event->pos();
+ CameraHelper::updateMousePos(event->pos());
+ }
+ d_ptr->m_mousePressed = Q3DMapsPrivate::MouseNone;
+}
+
+void Q3DMaps::mouseMoveEvent(QMouseEvent *event)
+{
+ if (Q3DMapsPrivate::MouseRotating == d_ptr->m_mousePressed) {
+ //qDebug() << "mouse moved while pressed" << event->pos();
+ d_ptr->m_mousePos = event->pos();
+ }
+#if 0
+ // TODO: Testi - laske kursorin sijainti scenessä
+ QPointF mouse3D((2.0f * event->pos().x() - width()) / height(),
+ 1.0f - (2.0f * event->pos().y()) / height());
+ //qDebug() << "mouse position in scene" << mouse3D;
+
+ // TODO: Testi laske focal point
+ GLfloat focalPoint = tan(45.0f / 2.0f);
+
+ // TODO: Testi - laske viewmatriisin kerroin
+ QVector3D worldRay = QVector3D(0.0f, 0.0f, 0.0f)
+ - QVector3D(mouse3D.x(), mouse3D.y(), -focalPoint);
+ //qDebug() << "worldRay" << worldRay;
+ // multiply viewmatrix with this to get something?
+#endif
+}
+
+void Q3DMaps::wheelEvent(QWheelEvent *event)
+{
+ if (d_ptr->m_zoomLevel > 100)
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 12;
+ else if (d_ptr->m_zoomLevel > 50)
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 60;
+ else
+ d_ptr->m_zoomLevel += event->angleDelta().y() / 120;
+ if (d_ptr->m_zoomLevel > 500)
+ d_ptr->m_zoomLevel = 500;
+ else if (d_ptr->m_zoomLevel < 10)
+ d_ptr->m_zoomLevel = 10;
+}
+
+void Q3DMaps::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+
+ // Set view port
+ if (d_ptr->m_zoomActivated)
+ d_ptr->m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
+ else
+ d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
+ d_ptr->m_zoomViewPort = QRect(0, 0, width(), height());
+
+ // Calculate zoom level based on aspect ratio
+ GLfloat div;
+ GLfloat zoomAdjustment;
+ div = qMin(width(), height());
+ zoomAdjustment = defaultRatio * ((width() / div) / (height() / div));
+ //qDebug() << "zoom adjustment" << zoomAdjustment;
+ d_ptr->m_zoomAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
+
+ // Re-init selection buffer
+ d_ptr->initSelectionBuffer();
+}
+
+void Q3DMaps::setBarSpecs(const QVector3D &thickness)
+{
+ d_ptr->m_barThickness = thickness;
+}
+
+void Q3DMaps::setBarType(BarStyle style, bool smooth)
+{
+ if (style == Bars) {
+ if (smooth)
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
+ else
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/bar");
+ } else if (style == Pyramids) {
+ if (smooth)
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
+ else
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
+ } else if (style == Cones) {
+ if (smooth)
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
+ else
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cone");
+ } else if (style == Cylinders) {
+ if (smooth)
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
+ else
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
+ } else if (style == Spheres) {
+ if (smooth)
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/sphereSmooth");
+ else
+ d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/sphere");
+ }
+ // Reload mesh data
+ if (d_ptr->m_isInitialized)
+ d_ptr->loadBarMesh();
+}
+
+void Q3DMaps::setMeshFileName(const QString &objFileName)
+{
+ d_ptr->m_objFile = objFileName;
+}
+
+void Q3DMaps::setCameraPreset(CameraPreset preset)
+{
+ CameraHelper::setCameraPreset(preset);
+}
+
+void Q3DMaps::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+{
+ d_ptr->m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
+ d_ptr->m_verticalRotation = qBound(0.0f, vertical, 90.0f);
+ d_ptr->m_zoomLevel = qBound(10, distance, 500);
+ CameraHelper::setCameraRotation(QPointF(d_ptr->m_horizontalRotation,
+ d_ptr->m_verticalRotation));
+ //qDebug() << "camera rotation set to" << d_ptr->m_horizontalRotation << d_ptr->m_verticalRotation;
+}
+
+void Q3DMaps::setTheme(ColorTheme theme)
+{
+ d_ptr->m_theme->useTheme(theme);
+ d_ptr->m_drawer->setTheme(*d_ptr->m_theme);
+ // Re-initialize shaders
+ if (!d_ptr->m_theme->m_uniformColor) {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+}
+
+void Q3DMaps::setBarColor(QColor baseColor, QColor heightColor, bool uniform)
+{
+ d_ptr->m_theme->m_baseColor = baseColor;
+ d_ptr->m_theme->m_heightColor = heightColor;
+ if (d_ptr->m_theme->m_uniformColor != uniform) {
+ // Re-initialize shaders
+ if (!d_ptr->m_theme->m_uniformColor) {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ }
+ d_ptr->m_theme->m_uniformColor = uniform;
+}
+
+void Q3DMaps::setSelectionMode(SelectionMode mode)
+{
+ d_ptr->m_selectionMode = mode;
+ // Disable zoom if mode changes
+ //d_ptr->m_zoomActivated = false;
+ //d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
+}
+
+void Q3DMaps::setWindowTitle(const QString &title)
+{
+ setTitle(title);
+}
+
+void Q3DMaps::setFontSize(float fontsize)
+{
+ d_ptr->m_fontSize = fontsize;
+ d_ptr->m_drawer->setFont(d_ptr->m_font);
+}
+
+void Q3DMaps::setFont(const QFont &font)
+{
+ d_ptr->m_font = font;
+ d_ptr->m_fontSize = font.pointSizeF();
+ d_ptr->m_drawer->setFont(font);
+}
+
+void Q3DMaps::setLabelTransparency(LabelTransparency transparency)
+{
+ d_ptr->m_labelTransparency = transparency;
+ d_ptr->m_drawer->setTransparency(transparency);
+}
+
+void Q3DMaps::setGridEnabled(bool enable)
+{
+ d_ptr->m_gridEnabled = enable;
+}
+
+void Q3DMaps::addDataItem(QDataItem* dataItem)
+{
+ d_ptr->m_data->addItem(dataItem);
+ // Get the limits
+ QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
+ d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
+ d_ptr->calculateHeightAdjustment(limits);
+}
+
+void Q3DMaps::addData(const QVector<QDataItem*> &data)
+{
+ // Convert to QDataRow
+ for (int i = 0; i < data.size(); i++)
+ d_ptr->m_data->addItem(data.at(i));
+ // Get the limits
+ QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
+ d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
+ d_ptr->calculateHeightAdjustment(limits);
+}
+
+void Q3DMaps::addData(const QDataRow &dataRow)
+{
+ for (int itemIdx = 0; itemIdx < dataRow.d_ptr->row().size(); itemIdx++)
+ d_ptr->m_data->addItem(dataRow.d_ptr->getItem(itemIdx));
+ // Get the limits
+ QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
+ d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
+ d_ptr->calculateHeightAdjustment(limits);
+}
+
+void Q3DMaps::setData(const QVector<QDataItem*> &dataRow)
+{
+ // Delete previous data
+ delete d_ptr->m_data;
+ // Convert to QDataRow
+ d_ptr->m_data = new QDataRow();
+ for (int i = 0; i < dataRow.size(); i++)
+ d_ptr->m_data->addItem(dataRow.at(i));
+ // Get the limits
+ QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
+ d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
+ d_ptr->calculateHeightAdjustment(limits);
+}
+
+void Q3DMaps::setData(QDataRow *dataRow)
+{
+ // Delete previous data
+ delete d_ptr->m_data;
+ // Set give data as new data
+ d_ptr->m_data = dataRow;
+ // Get the limits
+ QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
+ d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
+ d_ptr->calculateHeightAdjustment(limits);
+}
+
+void Q3DMaps::setAreaSpecs(const QRect &areaRect, const QImage &image)
+{
+ d_ptr->calculateSceneScalingFactors(areaRect);
+ setImage(image);
+}
+
+void Q3DMaps::setImage(const QImage &image)
+{
+ if (d_ptr->m_bgrTexture)
+ glDeleteTextures(1, &d_ptr->m_bgrTexture);
+ d_ptr->m_bgrTexture = d_ptr->m_textureHelper->create2DTexture(image, true, true);
+}
+
+Q3DMapsPrivate::Q3DMapsPrivate(Q3DMaps *q)
+ : q_ptr(q),
+ m_paintDevice(0),
+ m_barShader(0),
+ m_selectionShader(0),
+ m_backgroundShader(0),
+ m_labelShader(0),
+ m_barObj(0),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_labelObj(0),
+ m_objFile(QStringLiteral(":/defaultMeshes/bar")),
+ m_mousePressed(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_zoomLevel(100),
+ m_zoomAdjustment(1.0f),
+ m_horizontalRotation(-45.0f),
+ m_verticalRotation(15.0f),
+ m_barThickness(QVector3D(1.0f, 0.0f, 1.0f)),
+ m_heightNormalizer(0.0f),
+ m_yAdjustment(0.0f),
+ m_scaleFactor(1.0f),
+ m_theme(new Theme()),
+ m_isInitialized(false),
+ m_selectionMode(ModeBar),
+ m_selectedBar(0),
+ m_data(new QDataRow()),
+ m_axisLabelX(QStringLiteral("X")),
+ m_axisLabelZ(QStringLiteral("Z")),
+ m_axisLabelY(QStringLiteral("Y")),
+ m_sceneViewPort(0, 0, q->width(), q->height()),
+ m_zoomViewPort(0, 0, q->width(), q->height()),
+ m_zoomActivated(false),
+ m_textureHelper(new TextureHelper()),
+ m_labelTransparency(TransparencyNone),
+ m_fontSize(10.0f),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency)),
+ m_xFlipped(false),
+ m_zFlipped(false),
+ m_selectionFrameBuffer(0),
+ m_selectionDepthBuffer(0),
+ m_areaSize(QSizeF(1.0f, 1.0f)),
+ m_bgrTexture(0),
+ m_selectionTexture(0),
+ m_updateLabels(false),
+ m_gridEnabled(true)
+{
+ //m_data->d_ptr->setDrawer(m_drawer);
+ //QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Q3DMapsPrivate::updateTextures);
+}
+
+Q3DMapsPrivate::~Q3DMapsPrivate()
+{
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ //m_textureHelper->deleteTexture(&m_selectionDepthTexture);
+ m_textureHelper->deleteTexture(&m_bgrTexture);
+ delete m_data;
+ delete m_barShader;
+ delete m_selectionShader;
+ delete m_backgroundShader;
+ delete m_barObj;
+ delete m_backgroundObj;
+ delete m_gridLineObj;
+ delete m_textureHelper;
+ delete m_drawer;
+}
+
+void Q3DMapsPrivate::loadBarMesh()
+{
+ if (m_barObj)
+ delete m_barObj;
+ m_barObj = new ObjectHelper(m_objFile);
+ m_barObj->load();
+}
+
+void Q3DMapsPrivate::loadBackgroundMesh()
+{
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_backgroundObj->load();
+}
+
+void Q3DMapsPrivate::loadGridLineMesh()
+{
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+void Q3DMapsPrivate::loadLabelMesh()
+{
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void Q3DMapsPrivate::initShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_barShader)
+ delete m_barShader;
+ m_barShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
+ m_barShader->initialize();
+}
+
+void Q3DMapsPrivate::initSelectionShader()
+{
+ if (m_selectionShader)
+ delete m_selectionShader;
+ m_selectionShader = new ShaderHelper(q_ptr, QStringLiteral(":/shaders/vertexSelection"),
+ QStringLiteral(":/shaders/fragmentSelection"));
+ m_selectionShader->initialize();
+}
+
+void Q3DMapsPrivate::initSelectionBuffer()
+{
+ if (m_selectionTexture) {
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ //m_textureHelper->deleteTexture(&m_selectionDepthTexture);
+ }
+ m_selectionTexture = m_textureHelper->createSelectionTexture(q_ptr->size(),
+ m_selectionFrameBuffer,
+ m_selectionDepthBuffer);
+}
+
+void Q3DMapsPrivate::initBackgroundShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ if (m_backgroundShader)
+ delete m_backgroundShader;
+ m_backgroundShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
+ m_backgroundShader->initialize();
+}
+
+void Q3DMapsPrivate::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
+ m_labelShader->initialize();
+}
+
+void Q3DMapsPrivate::updateTextures()
+{
+ // Drawer has changed; this flag needs to be checked when checking if we need to update labels
+ m_updateLabels = true;
+}
+
+void Q3DMapsPrivate::calculateSceneScalingFactors(const QRect &areaRect)
+{
+ m_areaSize = areaRect.size();
+ // Calculate scaling factor so that we can be sure the whole area fits to positive z space
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()) / zComp;
+ //qDebug() << "scaleFactor" << m_scaleFactor;
+}
+
+void Q3DMapsPrivate::calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits)
+{
+ // 2.0f = max difference between minimum and maximum value after scaling with m_heightNormalizer
+ m_yAdjustment = 2.0f - ((limits.second - limits.first) / m_heightNormalizer);
+ //qDebug() << m_yAdjustment;
+}
+
+Q3DMapsPrivate::SelectionType Q3DMapsPrivate::isSelected(GLint bar, const QVector3D &selection)
+{
+ //static QVector3D prevSel = selection; // TODO: For debugging
+ SelectionType isSelectedType = SelectionNone;
+ if (selection == Utils::vectorFromColor(Qt::white))
+ return isSelectedType; // skip window
+ QVector3D current = QVector3D((GLubyte)(1.0f - ((GLdouble)(bar + 2)
+ / (GLdouble)(m_data->d_ptr->row().size() + 2))
+ * 255.0 + 0.49), // +0.49 to fix rounding (there are conversions from unsigned short to GLdouble and back)
+ (GLubyte)(((GLdouble)(bar + 2)
+ / (GLdouble)(m_data->d_ptr->row().size() + 2))
+ * 255.0 + 0.49), // +0.49 to fix rounding (there are conversions from unsigned short to GLdouble and back)
+ 0);
+ // TODO: For debugging
+ //if (selection != prevSel) {
+ // qDebug() << selection.x() << selection .y() << selection.z();
+ // prevSel = selection;
+ //}
+ if (current == selection)
+ isSelectedType = SelectionBar;
+// else if (current.y() == selection.y() && (m_selectionMode == ModeBarAndColumn
+// || m_selectionMode == ModeBarRowAndColumn
+// || m_selectionMode == ModeZoomColumn))
+// isSelectedType = SelectionColumn;
+// else if (current.x() == selection.x() && (m_selectionMode == ModeBarAndRow
+// || m_selectionMode == ModeBarRowAndColumn
+// || m_selectionMode == ModeZoomRow))
+// isSelectedType = SelectionRow;
+ return isSelectedType;
+}
+
+QTCOMMERCIALDATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dmaps.h b/src/datavis3d/engine/q3dmaps.h
new file mode 100644
index 00000000..ce9aa3cf
--- /dev/null
+++ b/src/datavis3d/engine/q3dmaps.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3DMAPS_H
+#define Q3DMAPS_H
+
+#include "QtDataVis3D/qdatavis3dglobal.h"
+#include "QtDataVis3D/qdatavis3namespace.h"
+#include "q3dwindow.h"
+
+class QOpenGLShaderProgram;
+class QImage;
+class QRect;
+
+QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DMapsPrivate;
+class QDataItem;
+class QDataRow;
+class QDataSet;
+class LabelItem;
+
+class QTCOMMERCIALDATAVIS3D_EXPORT Q3DMaps : public Q3DWindow
+{
+ Q_OBJECT
+
+public:
+ explicit Q3DMaps();
+ ~Q3DMaps();
+
+ void initialize();
+ void render();
+ void render(QPainter *painter);
+
+ // Add data item. New data item is appended to old data.
+ // ownership of data is transferred
+ void addDataItem(QDataItem *dataItem);
+
+ // Add data set. New data is appended to old data.
+ // ownership of data is transferred
+ void addData(const QVector<QDataItem*> &data);
+ // ownership of data is transferred
+ void addData(const QDataRow &data);
+
+ // Add data set. Old data is deleted.
+ // ownership of data is transferred
+ void setData(const QVector<QDataItem*> &data);
+ // ownership of data is transferred
+ void setData(QDataRow *data);
+
+ // bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value
+ void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 0.0f, 1.0f));//, joku enumi);
+
+ // bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc.
+ void setBarType(BarStyle style, bool smooth = false);
+
+ // override bar type with own mesh
+ void setMeshFileName(const QString &objFileName);
+
+ // Select preset camera placement
+ void setCameraPreset(CameraPreset preset);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (0...90) angles and distance in percentage (10...500))
+ void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+
+ // Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected)
+ void setTheme(ColorTheme theme);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height) color to change from bottom to top
+ void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true);
+
+ // TODO: valon siirto / asetus
+ // Change selection mode; single bar, bar and row, bar and column, or all
+ void setSelectionMode(SelectionMode mode);
+
+ // Set window title
+ void setWindowTitle(const QString &title);
+
+ // Font size adjustment (should it be in enum (smallest, smaller, small, normal, large, larger, largest), or just GLfloat?
+ void setFontSize(GLfloat fontsize);
+
+ // Set font
+ void setFont(const QFont &font);
+
+ // Label transparency adjustment
+ void setLabelTransparency(LabelTransparency transparency);
+
+ // Enable or disable background grid
+ void setGridEnabled(bool enable);
+
+ // Set area specs
+ void setAreaSpecs(const QRect &areaRect, const QImage &image);
+
+ // Set area image
+ void setImage(const QImage &image);
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ void drawScene();
+ QScopedPointer<Q3DMapsPrivate> d_ptr;
+ Q_DISABLE_COPY(Q3DMaps);
+};
+
+QTCOMMERCIALDATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dmaps_p.h b/src/datavis3d/engine/q3dmaps_p.h
new file mode 100644
index 00000000..088af5a6
--- /dev/null
+++ b/src/datavis3d/engine/q3dmaps_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DMAPS_P_H
+#define Q3DMAPS_P_H
+
+#include "qdatavis3dglobal.h"
+#include "qdatavis3namespace.h"
+#include <QOpenGLFunctions>
+#include <QFont>
+
+class QOpenGLPaintDevice;
+
+class QPoint;
+class QSizeF;
+
+QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DMaps;
+class QDataItem;
+class QDataRow;
+class QDataSet;
+class ShaderHelper;
+class ObjectHelper;
+class TextureHelper;
+class Theme;
+class Drawer;
+
+class Q3DMapsPrivate : public QObject
+{
+public:
+ enum SelectionType {
+ SelectionNone = 0,
+ SelectionBar,
+ SelectionRow,
+ SelectionColumn
+ };
+
+ enum MousePressType {
+ MouseNone = 0,
+ MouseOnScene,
+ MouseOnOverview,
+ MouseOnZoom,
+ MouseRotating
+ };
+
+public:
+ Q3DMapsPrivate(Q3DMaps *q);
+ ~Q3DMapsPrivate();
+
+ void loadBarMesh();
+ void loadBackgroundMesh();
+ void loadGridLineMesh();
+ void loadLabelMesh();
+ void initShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionShader();
+ void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionBuffer();
+ void updateTextures();
+ void calculateSceneScalingFactors(const QRect &areaRect);
+ void calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits);
+ SelectionType isSelected(GLint bar, const QVector3D &selection);
+
+ Q3DMaps *q_ptr;
+
+ QOpenGLPaintDevice *m_paintDevice;
+ ShaderHelper *m_barShader;
+ ShaderHelper *m_selectionShader;
+ ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_labelShader;
+ ObjectHelper *m_barObj;
+ ObjectHelper *m_backgroundObj;
+ ObjectHelper *m_gridLineObj;
+ ObjectHelper *m_labelObj;
+ QString m_objFile;
+ MousePressType m_mousePressed;
+ QPoint m_mousePos;
+ GLint m_zoomLevel;
+ GLfloat m_zoomAdjustment;
+ GLfloat m_horizontalRotation;
+ GLfloat m_verticalRotation;
+ QVector3D m_barThickness;
+ GLfloat m_heightNormalizer;
+ GLfloat m_yAdjustment;
+ GLfloat m_scaleFactor;
+ Theme *m_theme;
+ bool m_isInitialized;
+ SelectionMode m_selectionMode;
+ QDataItem *m_selectedBar;
+ QDataRow *m_data;
+ QString m_axisLabelX;
+ QString m_axisLabelZ;
+ QString m_axisLabelY;
+ QRect m_sceneViewPort;
+ QRect m_zoomViewPort;
+ bool m_zoomActivated;
+ TextureHelper *m_textureHelper;
+ LabelTransparency m_labelTransparency;
+ GLfloat m_fontSize;
+ QFont m_font;
+ Drawer *m_drawer;
+ bool m_xFlipped;
+ bool m_zFlipped;
+ QSizeF m_areaSize;
+ GLuint m_bgrTexture;
+ GLuint m_selectionTexture;
+ //GLuint m_selectionDepthTexture;
+ GLuint m_selectionFrameBuffer;
+ GLuint m_selectionDepthBuffer;
+ bool m_updateLabels;
+ bool m_gridEnabled;
+};
+
+QTCOMMERCIALDATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dwindow.h b/src/datavis3d/engine/q3dwindow.h
index 04bf4196..9958f7d9 100644
--- a/src/datavis3d/engine/q3dwindow.h
+++ b/src/datavis3d/engine/q3dwindow.h
@@ -48,7 +48,6 @@
#include <QOpenGLFunctions>
class QPainter;
-class QOpenGLPaintDevice;
QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
diff --git a/src/datavis3d/engine/qdataitem.cpp b/src/datavis3d/engine/qdataitem.cpp
index ac2f2705..72d7dcdd 100644
--- a/src/datavis3d/engine/qdataitem.cpp
+++ b/src/datavis3d/engine/qdataitem.cpp
@@ -69,6 +69,11 @@ void QDataItem::setValue(float value)
d_ptr->m_value = value;
}
+void QDataItem::setPosition(const QPointF &position)
+{
+ d_ptr->m_position = position;
+}
+
QDataItemPrivate::QDataItemPrivate(QDataItem *q, float value, const QString &label)
: q_ptr(q),
m_value(value),
@@ -133,12 +138,7 @@ LabelItem QDataItemPrivate::selectionLabel()
return m_selectionLabel;
}
-void QDataItemPrivate::setPosition(const QPoint &position)
-{
- m_position = position;
-}
-
-QPoint QDataItemPrivate::position()
+QPointF QDataItemPrivate::position()
{
return m_position;
}
diff --git a/src/datavis3d/engine/qdataitem.h b/src/datavis3d/engine/qdataitem.h
index 57cebfdb..7de69cab 100644
--- a/src/datavis3d/engine/qdataitem.h
+++ b/src/datavis3d/engine/qdataitem.h
@@ -46,6 +46,8 @@
#include <QScopedPointer>
#include <QString>
+class QPointF;
+
QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
class QDataItemPrivate;
@@ -58,6 +60,7 @@ public:
void setLabel(const QString &label, bool prepend = false); // label for value, unit for example
void setValue(float value);
+ void setPosition(const QPointF &position);
private:
QScopedPointer<QDataItemPrivate> d_ptr;
diff --git a/src/datavis3d/engine/qdataitem_p.h b/src/datavis3d/engine/qdataitem_p.h
index 9ce4ecb7..f14fe175 100644
--- a/src/datavis3d/engine/qdataitem_p.h
+++ b/src/datavis3d/engine/qdataitem_p.h
@@ -82,9 +82,7 @@ class QDataItemPrivate
// Selection label item (containing specialar selection texture, if mode is activated)
void setSelectionLabel(const LabelItem &label);
LabelItem selectionLabel();
- // Position in set QPoint(row, column)
- void setPosition(const QPoint &position);
- QPoint position();
+ QPointF position();
private:
QDataItem *q_ptr;
@@ -94,7 +92,7 @@ class QDataItemPrivate
QVector3D m_translation;
LabelItem m_label;
LabelItem m_selectionLabel;
- QPoint m_position;
+ QPointF m_position;
friend class QDataItem;
};
diff --git a/src/datavis3d/global/qdatavis3namespace.h b/src/datavis3d/global/qdatavis3namespace.h
index ebd5a3eb..2177b175 100644
--- a/src/datavis3d/global/qdatavis3namespace.h
+++ b/src/datavis3d/global/qdatavis3namespace.h
@@ -43,18 +43,24 @@
#define QVIS3DNAMESPACE_H
#include "qdatavis3dglobal.h"
+#include <QOpenGLFunctions>
+#include <QVector3D>
QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE
// Constants used in several files
-const float m_pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f;
+const GLfloat m_pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f;
+const GLfloat zComp = 10.0f; // Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly
+const QVector3D defaultLightPos = QVector3D(0.0f, 3.0f, zComp);
+const GLfloat defaultRatio = 1.0f / 1.6f; // default aspect ratio 16:10
// Enums used in several files
enum BarStyle {
Bars = 0,
Pyramids,
Cones,
- Cylinders
+ Cylinders,
+ Spheres
};
enum CameraPreset {