summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2013-08-05 08:58:37 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2013-08-05 10:59:59 +0300
commitbfc8e5e40eafea00bdc481a663e229a23dc8f83b (patch)
tree58487c4e8cfe60ada257e4e3e2aae3ec1b05586a
parent2b3dde773f730c7b32268751de42ca8724785553 (diff)
Q3DScatter: Scene drawing works
+ added an example utilizing sctter chart - labels still disabled and untested - QML still missing Change-Id: I98b3d6701ca6c73305ba3984f60923939e7988e6 Change-Id: I98b3d6701ca6c73305ba3984f60923939e7988e6 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
-rw-r--r--examples/examples.pro3
-rw-r--r--examples/scatterchart/doc/src/scatterchart.qdoc38
-rw-r--r--examples/scatterchart/main.cpp227
-rw-r--r--examples/scatterchart/scatterchart.cpp287
-rw-r--r--examples/scatterchart/scatterchart.h88
-rw-r--r--examples/scatterchart/scatterchart.pro10
-rw-r--r--src/datavis3d/doc/src/qtdatavis3d-index.qdoc1
-rw-r--r--src/datavis3d/engine/engine.qrc2
-rw-r--r--src/datavis3d/engine/meshes/scatterdot.obj28
-rw-r--r--src/datavis3d/engine/meshes/scatterdotFlat.obj28
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp29
-rw-r--r--src/datavis3d/engine/scatter3drenderer.cpp282
-rw-r--r--src/datavis3d/global/qdatavis3dnamespace.h3
13 files changed, 896 insertions, 130 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
index 348aab53..636d7022 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -5,6 +5,7 @@ SUBDIRS += barchart \
mapdata \
qmlbarchart \
qmlmaps \
- surfacechart
+ surfacechart \
+ scatterchart
qtHaveModule(multimedia):!android: SUBDIRS += spectrum
diff --git a/examples/scatterchart/doc/src/scatterchart.qdoc b/examples/scatterchart/doc/src/scatterchart.qdoc
new file mode 100644
index 00000000..ac3d758a
--- /dev/null
+++ b/examples/scatterchart/doc/src/scatterchart.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example scatterchart
+ \title Scatter Chart Example
+
+ The scatterchart example shows how to make a simple 3D scatter chart using Q3DScatter and
+ combining the use of widgets for adjusting several adjustable qualities.
+
+ \image scatterchart-example.png
+
+ TODO
+*/
diff --git a/examples/scatterchart/main.cpp b/examples/scatterchart/main.cpp
new file mode 100644
index 00000000..6cec6988
--- /dev/null
+++ b/examples/scatterchart/main.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scatterchart.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QSlider>
+#include <QComboBox>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+
+ Q3DScatter *chart = new Q3DScatter();
+ QSize screenSize = chart->screen()->size();
+
+ QWidget *container = QWidget::createWindowContainer(chart);
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ widget->setWindowTitle(QStringLiteral("values of some things in something"));
+
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+
+// QPushButton *dataButton = new QPushButton(widget);
+// dataButton->setText(QStringLiteral("Add a row of random data"));
+// dataButton->setEnabled(false);
+
+ QPushButton *themeButton = new QPushButton(widget);
+ themeButton->setText(QStringLiteral("Change theme"));
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QPushButton *styleButton = new QPushButton(widget);
+ styleButton->setText(QStringLiteral("Change bar style"));
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Change camera preset"));
+
+// QPushButton *selectionButton = new QPushButton(widget);
+// selectionButton->setText(QStringLiteral("Change selection mode"));
+
+ QCheckBox *gridCheckBox = new QCheckBox(widget);
+ gridCheckBox->setText(QStringLiteral("Show grid"));
+ gridCheckBox->setChecked(true);
+
+// QCheckBox *rotationCheckBox = new QCheckBox(widget);
+// rotationCheckBox->setText("Rotate with slider");
+
+// QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget);
+// rotationSliderX->setTickInterval(1);
+// rotationSliderX->setMinimum(-180);
+// rotationSliderX->setValue(0);
+// rotationSliderX->setMaximum(180);
+// rotationSliderX->setEnabled(false);
+// QSlider *rotationSliderY = new QSlider(Qt::Horizontal, widget);
+// rotationSliderY->setTickInterval(1);
+// rotationSliderY->setMinimum(0);
+// rotationSliderY->setValue(0);
+// rotationSliderY->setMaximum(90);
+// rotationSliderY->setEnabled(false);
+
+// QSlider *sizeSliderX = new QSlider(Qt::Horizontal, widget);
+// sizeSliderX->setTickInterval(1);
+// sizeSliderX->setMinimum(1);
+// sizeSliderX->setValue(100);
+// sizeSliderX->setMaximum(100);
+// QSlider *sizeSliderZ = new QSlider(Qt::Horizontal, widget);
+// sizeSliderZ->setTickInterval(1);
+// sizeSliderZ->setMinimum(1);
+// sizeSliderZ->setValue(100);
+// sizeSliderZ->setMaximum(100);
+
+// QComboBox *valueDimension = new QComboBox(widget);
+// valueDimension->addItem(QStringLiteral("Height"));
+// valueDimension->addItem(QStringLiteral("Width"));
+// valueDimension->addItem(QStringLiteral("Depth"));
+// valueDimension->addItem(QStringLiteral("Radius"));
+// valueDimension->addItem(QStringLiteral("All"));
+// valueDimension->setCurrentIndex(4);
+
+ QComboBox *shadowQuality = new QComboBox(widget);
+ shadowQuality->addItem(QStringLiteral("None"));
+ shadowQuality->addItem(QStringLiteral("Low"));
+ shadowQuality->addItem(QStringLiteral("Medium"));
+ shadowQuality->addItem(QStringLiteral("High"));
+ shadowQuality->setCurrentIndex(1);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
+ fontSizeSlider->setTickInterval(1);
+ fontSizeSlider->setMinimum(1);
+ fontSizeSlider->setValue(80);
+ fontSizeSlider->setMaximum(200);
+
+// vLayout->addWidget(rotationCheckBox, 0, Qt::AlignTop);
+// vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop);
+// vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop);
+// vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar size")));
+// vLayout->addWidget(sizeSliderX, 0, Qt::AlignTop);
+// vLayout->addWidget(sizeSliderZ, 0, Qt::AlignTop);
+// vLayout->addWidget(dataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(themeButton, 0, Qt::AlignTop);
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(styleButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+// vLayout->addWidget(new QLabel(QStringLiteral("Apply value to:")));
+// vLayout->addWidget(valueDimension, 0, Qt::AlignTop);
+// vLayout->addWidget(selectionButton, 0, Qt::AlignTop);
+ vLayout->addWidget(gridCheckBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")));
+ vLayout->addWidget(shadowQuality);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change font")));
+ vLayout->addWidget(fontList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust font size")));
+ vLayout->addWidget(fontSizeSlider, 1, Qt::AlignTop);
+// // TODO: Add example for setMeshFileName
+
+ widget->show();
+
+ ScatterDataModifier *modifier = new ScatterDataModifier(chart);
+
+// QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &MapsModifier::rotateX);
+// QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &MapsModifier::rotateY);
+
+// QObject::connect(sizeSliderX, &QSlider::valueChanged, modifier, &MapsModifier::setSpecsX);
+// QObject::connect(sizeSliderZ, &QSlider::valueChanged, modifier, &MapsModifier::setSpecsZ);
+
+ QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
+ &ScatterDataModifier::changeFontSize);
+
+ QObject::connect(styleButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeStyle);
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changePresetCamera);
+ QObject::connect(themeButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeTheme);
+ QObject::connect(labelButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeTransparency);
+// QObject::connect(dataButton, &QPushButton::clicked, modifier, &MapsModifier::addBars);
+// QObject::connect(selectionButton, &QPushButton::clicked, modifier,
+// &MapsModifier::changeSelectionMode);
+
+// QObject::connect(valueDimension, SIGNAL(currentIndexChanged(int)), modifier,
+// SLOT(changeValueDimension(int)));
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+ QObject::connect(modifier, &ScatterDataModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(chart, &Q3DScatter::shadowQualityChanged, modifier,
+ &ScatterDataModifier::shadowQualityUpdatedByVisual);
+
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
+ &ScatterDataModifier::changeFont);
+
+ QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setGridEnabled);
+
+// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderX,
+// &QSlider::setEnabled);
+// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderX,
+// &QSlider::setValue);
+// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
+// &QSlider::setEnabled);
+// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
+// &QSlider::setValue);
+
+ modifier->start();
+
+ return app.exec();
+}
diff --git a/examples/scatterchart/scatterchart.cpp b/examples/scatterchart/scatterchart.cpp
new file mode 100644
index 00000000..1c91f6d7
--- /dev/null
+++ b/examples/scatterchart/scatterchart.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scatterchart.h"
+#include "qscatterdataproxy.h"
+#include <QImage>
+#include <QFile>
+
+using namespace QtDataVis3D;
+
+ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
+ : m_chart(scatter),
+ m_fontSize(80.0f)
+{
+ m_chart->setFontSize(m_fontSize);
+
+ m_chart->setTheme(ThemeBlueIcy);
+ m_chart->setShadowQuality(ShadowMedium);
+
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ m_chart->setDataProxy(proxy);
+}
+
+ScatterDataModifier::~ScatterDataModifier()
+{
+ delete m_chart;
+}
+
+void ScatterDataModifier::start()
+{
+ addData();
+}
+
+void ScatterDataModifier::addData()
+{
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ QScatterDataItem *item;
+#if 0
+ item = new QScatterDataItem();
+ item->setValue(-1.0);
+ //item->setLabel("Oulu");
+ item->setScatterPosition(QPointF(0.0f, 0.0f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(1.0);
+ //item->setLabel("Kemi");
+ item->setScatterPosition(QPointF(1.0f, 1.0f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(0.5);
+ //item->setLabel("Rovaniemi");
+ item->setScatterPosition(QPointF(-1.0f, -1.0f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(-0.5);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(0.5f, -0.5f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(-0.75);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(0.25f, 0.25f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(0.75);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(0.75f, -0.75f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(0.6);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(0.1f, -0.2f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(-0.4);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(0.2f, -0.05f));
+ dataArray->append(*item);
+ delete item;
+
+ item = new QScatterDataItem();
+ item->setValue(0.35);
+ //item->setLabel("Kuusamo");
+ item->setScatterPosition(QPointF(-0.25f, 0.35f));
+ dataArray->append(*item);
+ delete item;
+#else
+ for (int i = 0; i < 500; i++) {
+ item = new QScatterDataItem();
+ item->setValue((qreal)(rand() % 100) / 100.0 - (qreal)(rand() % 100) / 100.0);
+ item->setScatterPosition(
+ QPointF((qreal)(rand() % 100) / 100.0 - (qreal)(rand() % 100) / 100.0,
+ (qreal)(rand() % 100) / 100.0 - (qreal)(rand() % 100) / 100.0));
+ dataArray->append(*item);
+ delete item;
+ }
+#endif
+ static_cast<QScatterDataProxy *>(m_chart->dataProxy())->resetArray(dataArray);
+}
+
+void ScatterDataModifier::changeStyle()
+{
+ static int model = 0;
+ switch (model) {
+ case 0:
+ m_chart->setBarType(Dots, false);
+ break;
+ case 1:
+ m_chart->setBarType(Dots, true);
+ break;
+ case 2:
+ m_chart->setBarType(Spheres, false);
+ break;
+ case 3:
+ m_chart->setBarType(Spheres, true);
+ break;
+ }
+ model++;
+ if (model > 3)
+ model = 0;
+}
+
+void ScatterDataModifier::changePresetCamera()
+{
+ static int preset = PresetFrontLow;
+
+ m_chart->setCameraPreset((CameraPreset)preset);
+
+ if (++preset > PresetDirectlyAboveCCW45)
+ preset = PresetFrontLow;
+}
+
+void ScatterDataModifier::changeTheme()
+{
+ static int theme = ThemeSystem;
+
+ m_chart->setTheme((ColorTheme)theme);
+
+ if (++theme > ThemeLight)
+ theme = ThemeSystem;
+}
+
+void ScatterDataModifier::changeTransparency()
+{
+ static int transparency = TransparencyNone;
+
+ m_chart->setLabelTransparency((LabelTransparency)transparency);
+
+ if (++transparency > TransparencyNoBackground)
+ transparency = TransparencyFromTheme;
+}
+
+//void ScatterDataModifier::changeValueDimension(int dimension)
+//{
+// m_chart->setBarSpecs(m_barSpecs, (Q3DMaps::AdjustmentDirection)dimension);
+//}
+
+void ScatterDataModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSizeF(m_fontSize);
+ //qDebug() << newFont << newFont.style();
+ m_chart->setFont(newFont);
+}
+
+void ScatterDataModifier::changeFontSize(int fontsize)
+{
+ m_fontSize = fontsize;
+ m_chart->setFontSize((GLfloat)m_fontSize);
+}
+
+void ScatterDataModifier::shadowQualityUpdatedByVisual(ShadowQuality sq)
+{
+ int quality = 0;
+ switch (sq) {
+ case ShadowLow:
+ quality = 1;
+ break;
+ case ShadowMedium:
+ quality = 2;
+ break;
+ case ShadowHigh:
+ quality = 3;
+ break;
+ }
+
+ // Updates the UI component to show correct shadow quality
+ emit shadowQualityChanged(quality);
+}
+
+void ScatterDataModifier::changeShadowQuality(int quality)
+{
+ ShadowQuality sq = ShadowNone;
+ switch (quality) {
+ case 1:
+ sq = ShadowLow;
+ break;
+ case 2:
+ sq = ShadowMedium;
+ break;
+ case 3:
+ sq = ShadowHigh;
+ break;
+ }
+ m_chart->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
+}
+
+void ScatterDataModifier::setGridEnabled(int enabled)
+{
+ m_chart->setGridVisible((bool)enabled);
+}
+
+//void ScatterDataModifier::rotateX(int rotation)
+//{
+// m_xRotation = rotation;
+// m_chart->setCameraPosition(m_xRotation, m_yRotation);
+//}
+
+//void ScatterDataModifier::rotateY(int rotation)
+//{
+// m_yRotation = rotation;
+// m_chart->setCameraPosition(m_xRotation, m_yRotation);
+//}
+
+//void ScatterDataModifier::setSpecsX(int barwidth)
+//{
+// m_barWidth = (float)barwidth / 100.0f;
+// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
+//}
+
+//void ScatterDataModifier::setSpecsZ(int bardepth)
+//{
+// m_barDepth = (float)bardepth / 100.0f;
+// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
+//}
diff --git a/examples/scatterchart/scatterchart.h b/examples/scatterchart/scatterchart.h
new file mode 100644
index 00000000..449c21c5
--- /dev/null
+++ b/examples/scatterchart/scatterchart.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of QtDataVis3D module.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include "q3dscatter.h"
+
+#include <QFont>
+#include <QDebug>
+//#include <QVector3D>
+
+using namespace QtDataVis3D;
+
+class ScatterDataModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ScatterDataModifier(Q3DScatter *scatter);
+ ~ScatterDataModifier();
+
+ void addData();
+ void changeStyle();
+ void changePresetCamera();
+ void changeTheme();
+// void changeSelectionMode();
+ void changeTransparency();
+ void changeFont(const QFont &font);
+ void changeFontSize(int fontsize);
+// void rotateX(int rotation);
+// void rotateY(int rotation);
+ void setGridEnabled(int enabled);
+// void setSpecsX(int barwidth);
+// void setSpecsZ(int bardepth);
+ void start();
+
+public slots:
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(ShadowQuality shadowQuality);
+
+signals:
+ void shadowQualityChanged(int quality);
+
+private:
+ Q3DScatter *m_chart;
+ //QRect m_areaRect;
+ int m_fontSize;
+ //QVector3D m_barSpecs;
+};
+
+#endif
diff --git a/examples/scatterchart/scatterchart.pro b/examples/scatterchart/scatterchart.pro
new file mode 100644
index 00000000..5dee59fd
--- /dev/null
+++ b/examples/scatterchart/scatterchart.pro
@@ -0,0 +1,10 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp scatterchart.cpp
+HEADERS += scatterchart.h
+
+QT += widgets
+
+INSTALLS += target
diff --git a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
index 04564a5a..8a6f1abe 100644
--- a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
+++ b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
@@ -63,6 +63,7 @@
\li \l{Qt Quick 2 Barchart Example}
\li \l{Qt Quick 2 Maps Example}
\li \l{Rainfall Example}
+ \li \l{Scatter Chart Example}
\li \l{Spectrum Example}
\li \l{Widget Example}
\endlist
diff --git a/src/datavis3d/engine/engine.qrc b/src/datavis3d/engine/engine.qrc
index 5c9df92a..af6e899d 100644
--- a/src/datavis3d/engine/engine.qrc
+++ b/src/datavis3d/engine/engine.qrc
@@ -26,6 +26,8 @@
<file alias="bevelbarSmoothFull">meshes/barFilledSmooth.obj</file>
<file alias="barFull">meshes/cubeFilledFlat.obj</file>
<file alias="barSmoothFull">meshes/cubeFilledSmooth.obj</file>
+ <file alias="dotSmooth">meshes/scatterdot.obj</file>
+ <file alias="dot">meshes/scatterdotFlat.obj</file>
</qresource>
<qresource prefix="/shaders">
<file alias="fragment">shaders/default.frag</file>
diff --git a/src/datavis3d/engine/meshes/scatterdot.obj b/src/datavis3d/engine/meshes/scatterdot.obj
new file mode 100644
index 00000000..d994a80f
--- /dev/null
+++ b/src/datavis3d/engine/meshes/scatterdot.obj
@@ -0,0 +1,28 @@
+# Blender v2.66 (sub 0) OBJ File: 'scatterdot.blend'
+# www.blender.org
+o Cone
+v 0.000000 -0.500000 -1.000000
+v 0.866025 -0.500000 0.500000
+v 0.000000 0.500000 0.000000
+v -0.866025 -0.500000 0.500000
+vt 0.999727 0.000000
+vt 1.000000 0.492691
+vt 0.522886 0.369782
+vt 0.477114 0.973202
+vt 0.000000 1.096111
+vt 0.000273 0.603420
+vt 0.523159 0.985382
+vt 0.522886 0.492691
+vt 1.000000 0.615600
+vt 0.000000 0.603420
+vt 0.000617 0.000000
+vt 0.522886 0.302245
+vn -0.833033 -0.273293 0.480941
+vn 0.000000 0.999969 0.000000
+vn 0.000000 -0.273293 -0.961913
+vn 0.833033 -0.273293 0.480941
+s 1
+f 4/1/1 3/2/2 1/3/3
+f 1/4/3 3/5/2 2/6/4
+f 2/7/4 3/8/2 4/9/1
+f 1/10/3 2/11/4 4/12/1
diff --git a/src/datavis3d/engine/meshes/scatterdotFlat.obj b/src/datavis3d/engine/meshes/scatterdotFlat.obj
new file mode 100644
index 00000000..4052738d
--- /dev/null
+++ b/src/datavis3d/engine/meshes/scatterdotFlat.obj
@@ -0,0 +1,28 @@
+# Blender v2.66 (sub 0) OBJ File: 'scatterdot.blend'
+# www.blender.org
+o Cone
+v 0.000000 -0.500000 -1.000000
+v 0.866025 -0.500000 0.500000
+v 0.000000 0.500000 0.000000
+v -0.866025 -0.500000 0.500000
+vt 0.999727 0.000000
+vt 1.000000 0.492691
+vt 0.522886 0.369782
+vt 0.477114 0.973202
+vt 0.000000 1.096111
+vt 0.000273 0.603420
+vt 0.523159 0.985382
+vt 0.522886 0.492691
+vt 1.000000 0.615600
+vt 0.000000 0.603420
+vt 0.000617 0.000000
+vt 0.522886 0.302245
+vn -0.774597 0.447214 -0.447214
+vn 0.774597 0.447214 -0.447214
+vn -0.000000 0.447214 0.894427
+vn 0.000000 -1.000000 -0.000000
+s off
+f 4/1/1 3/2/1 1/3/1
+f 1/4/2 3/5/2 2/6/2
+f 2/7/3 3/8/3 4/9/3
+f 1/10/4 2/11/4 4/12/4
diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp
index 50c390b5..23324b2a 100644
--- a/src/datavis3d/engine/scatter3dcontroller.cpp
+++ b/src/datavis3d/engine/scatter3dcontroller.cpp
@@ -68,7 +68,7 @@ Scatter3DController::Scatter3DController(QRect boundRect)
m_isBarSpecRelative(true),
m_barThickness(QSizeF(0.75f, 0.75f)),
m_barSpacing(m_barThickness * 3.0f),
- m_objFile(QStringLiteral(":/defaultMeshes/bar")),
+ m_objFile(QStringLiteral(":/defaultMeshes/dot")),
m_font(QFont(QStringLiteral("Arial"))),
m_isGridEnabled(true),
m_isBackgroundEnabled(true),
@@ -371,31 +371,16 @@ QString Scatter3DController::objFile()
void Scatter3DController::setBarType(BarStyle style, bool smooth)
{
- if (style == Bars) {
+ if (style == Spheres) {
if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
+ m_objFile = QStringLiteral(":/defaultMeshes/sphereSmooth");
else
- m_objFile = QStringLiteral(":/defaultMeshes/bar");
- } else if (style == Pyramids) {
+ m_objFile = QStringLiteral(":/defaultMeshes/sphere");
+ } else {
if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
+ m_objFile = QStringLiteral(":/defaultMeshes/dotSmooth");
else
- m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
- } else if (style == Cones) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/cone");
- } else if (style == Cylinders) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
- } else if (style == BevelBars) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/bevelbarSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/bevelbar");
+ m_objFile = QStringLiteral(":/defaultMeshes/dot");
}
emit objFileChanged(m_objFile);
diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp
index 0847df9c..4cc8bfec 100644
--- a/src/datavis3d/engine/scatter3drenderer.cpp
+++ b/src/datavis3d/engine/scatter3drenderer.cpp
@@ -74,6 +74,8 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+const GLfloat aspectRatio = 2.0f; // TODO: Calculate
+const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
const GLfloat gridLineWidth = 0.005f;
static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
@@ -83,8 +85,8 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_hasNegativeValues(false),
m_selectedBar(0),
m_previouslySelectedBar(0),
- m_tickCount(0),
- m_tickStep(0),
+ m_tickCount(5),
+ m_tickStep(0.2f),
m_xFlipped(false),
m_zFlipped(false),
m_updateLabels(false),
@@ -116,7 +118,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_scaleFactor(0),
m_maxSceneSize(40.0),
m_selection(selectionSkipColor),
- m_areaSize(QSizeF(1.0f, 1.0f)),
+ m_areaSize(QSizeF(2.0f, 2.0f)),
m_hasHeightAdjustmentChanged(true),
m_dataProxy(0),
m_valueUpdateNeeded(false)
@@ -125,6 +127,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_numFrames(0)
#endif
{
+ //qDebug() << __FUNCTION__;
m_dummyRenderItem.setRenderer(this);
// Listen to changes in the drawer
@@ -190,6 +193,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
Scatter3DRenderer::~Scatter3DRenderer()
{
+ //qDebug() << __FUNCTION__;
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->deleteTexture(&m_selectionTexture);
@@ -208,6 +212,7 @@ Scatter3DRenderer::~Scatter3DRenderer()
void Scatter3DRenderer::initializeOpenGL()
{
+ //qDebug() << __FUNCTION__;
initializeOpenGLFunctions();
m_textureHelper = new TextureHelper();
@@ -303,6 +308,7 @@ void Scatter3DRenderer::render(QScatterDataProxy *dataProxy,
Q_UNUSED(xLabel);
Q_UNUSED(yLabel);
Q_UNUSED(zLabel);
+ //qDebug() << __FUNCTION__;
#ifdef DISPLAY_RENDER_SPEED
// For speed computation
@@ -369,11 +375,9 @@ void Scatter3DRenderer::render(QScatterDataProxy *dataProxy,
void Scatter3DRenderer::drawScene(CameraHelper *camera,
const GLuint defaultFboHandle)
{
+ //qDebug() << __FUNCTION__;
GLfloat backgroundRotation = 0;
- GLfloat barPos = 0;
- GLfloat rowPos = 0;
-
// Specify viewport
glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
m_mainViewPort.width(), m_mainViewPort.height());
@@ -416,9 +420,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
GLfloat heightMultiplier = 1.0f;
GLfloat widthMultiplier = 1.0f;
GLfloat depthMultiplier = 1.0f;
- GLfloat heightScaler = 1.0f;
- GLfloat widthScaler = 1.0f;
- GLfloat depthScaler = 1.0f;
+ GLfloat heightScaler = 0.0f;
+ GLfloat widthScaler = 0.0f;
+ GLfloat depthScaler = 0.0f;
// switch (m_adjustDirection) {
// case Q3DMaps::AdjustHeight:
// widthMultiplier = 0.0f;
@@ -509,11 +513,14 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 MVPMatrix;
modelMatrix.translate(item.translation().x(),
- heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().y(),
item.translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
- heightMultiplier * item.height() + heightScaler,
- depthMultiplier * item.height() + depthScaler));
+ modelMatrix.scale(QVector3D(widthMultiplier * 0.1f + widthScaler,
+ heightMultiplier * 0.1f + heightScaler,
+ depthMultiplier * 0.1f + depthScaler));
+ //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -595,11 +602,14 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 MVPMatrix;
modelMatrix.translate(item.translation().x(),
- heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().y(),
item.translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
- heightMultiplier * item.height() + heightScaler,
- depthMultiplier * item.height() + depthScaler));
+ modelMatrix.scale(QVector3D(widthMultiplier * 0.1f + widthScaler,
+ heightMultiplier * 0.1f + heightScaler,
+ depthMultiplier * 0.1f + depthScaler));
+ //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
@@ -641,7 +651,6 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
glEnable(GL_DITHER);
// Read color under cursor
- // Read color under cursor
if (Scatter3DController::MouseOnScene == m_controller->mouseState())
m_selection = Utils::getSelection(m_controller->mousePosition(),
m_cachedBoundingRect.height());
@@ -678,6 +687,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
m_labelShader->release();
#endif
}
+#endif
+
#if 1
// Bind bar shader
m_barShader->bind();
@@ -686,8 +697,6 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
glEnable(GL_TEXTURE_2D);
// Draw bars
- // TODO: Handle zoom by camera transformations
-
bool barSelectionFound = false;
for (int bar = 0; bar < m_renderItemArray.size(); bar++) {
ScatterRenderItem &item = m_renderItemArray[bar];
@@ -700,14 +709,20 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 itModelMatrix;
modelMatrix.translate(item.translation().x(),
- heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().y(),
item.translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
- heightMultiplier * item.height() + heightScaler,
- depthMultiplier * item.height() + depthScaler));
- itModelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
- heightMultiplier * item.height() + heightScaler,
- depthMultiplier * item.height() + depthScaler));
+ modelMatrix.scale(QVector3D(widthMultiplier * 0.1f + widthScaler,
+ heightMultiplier * 0.1f + heightScaler,
+ depthMultiplier * 0.1f + depthScaler));
+ // modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
+ itModelMatrix.scale(QVector3D(widthMultiplier * 0.1f + widthScaler,
+ heightMultiplier * 0.1f + heightScaler,
+ depthMultiplier * 0.1f + depthScaler));
+ // itModelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
+ // heightMultiplier * item.height() + heightScaler,
+ // depthMultiplier * item.height() + depthScaler));
#ifdef SHOW_DEPTH_TEXTURE_SCENE
MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -780,7 +795,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// Release bar shader
m_barShader->release();
+#endif
+#if 1
// Bind background shader
m_backgroundShader->bind();
@@ -793,14 +810,18 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
- 1.0f,
- m_columnDepth / m_scaleFactor));
+ modelMatrix.translate(0.0f, -m_yAdjustment, zComp);
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ backgroundMargin / m_scaleFactor,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
- 1.0f,
- m_columnDepth / m_scaleFactor));
+ itModelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ backgroundMargin / m_scaleFactor,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
#ifdef SHOW_DEPTH_TEXTURE_SCENE
MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -850,7 +871,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// Disable textures
glDisable(GL_TEXTURE_2D);
+#endif
+#if 1
+ // TODO: Grid lines cannot be done as in bars; we need configurable lines. Let's use ticks for now.
// Draw grid lines
if (m_cachedIsGridEnabled && m_heightNormalizer) {
// Bind bar shader
@@ -864,19 +888,28 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme.m_ambientStrength);
// Floor lines: rows
- for (GLfloat row = 0.0f; row <= m_cachedRowCount; row++) {
+ GLfloat heightStep = m_tickStep;
+ GLfloat startLine = -m_heightNormalizer;
+
+ for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
+ lineHeight += heightStep) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
- modelMatrix.translate(0.0f, -m_yAdjustment,
- (m_columnDepth - rowPos) / m_scaleFactor + zComp);
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
+ modelMatrix.translate(
+ 0.0f,
+ -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor,
+ (aspectRatio * lineHeight) / (m_heightNormalizer * m_scaleFactor) + zComp);
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ gridLineWidth, gridLineWidth));
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -909,20 +942,25 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
}
// Floor lines: columns
- for (GLfloat bar = 0.0f; bar <= m_cachedColumnCount; bar++) {
+ for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
+ lineHeight += heightStep) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- barPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- -m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
- itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
-
+ modelMatrix.translate(
+ (aspectRatio * lineHeight) / (m_heightNormalizer * m_scaleFactor),
+ -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor,
+ zComp);
+ modelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+ itModelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -955,17 +993,6 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
}
// Wall lines: back wall
- GLfloat heightStep = m_heightNormalizer / 5.0f; // default to 5 lines
- GLfloat startLine;
-
- if (m_tickCount > 0)
- heightStep = m_tickStep;
-
- if (m_hasNegativeValues)
- startLine = -m_heightNormalizer;
- else
- startLine = heightStep;
-
for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
lineHeight += heightStep) {
QMatrix4x4 modelMatrix;
@@ -974,18 +1001,26 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 itModelMatrix;
if (m_zFlipped) {
- modelMatrix.translate(0.0f,
- 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
- m_columnDepth / m_scaleFactor + zComp);
+ modelMatrix.translate(
+ 0.0f,
+ lineHeight / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment,
+ (aspectRatio * backgroundMargin * m_areaSize.height() / m_scaleFactor)
+ + zComp);
} else {
- modelMatrix.translate(0.0f,
- 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
- -m_columnDepth / m_scaleFactor + zComp);
+ modelMatrix.translate(
+ 0.0f,
+ lineHeight / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment,
+ -(aspectRatio * backgroundMargin * m_areaSize.height() / m_scaleFactor)
+ + zComp);
}
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor),
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor),
+ gridLineWidth, gridLineWidth));
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -1026,18 +1061,24 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 itModelMatrix;
if (m_xFlipped) {
- modelMatrix.translate(m_rowWidth / m_scaleFactor,
- 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
- zComp);
+ modelMatrix.translate(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ lineHeight / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment,
+ zComp);
} else {
- modelMatrix.translate(-m_rowWidth / m_scaleFactor,
- 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
- zComp);
+ modelMatrix.translate(
+ -(aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ lineHeight / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment,
+ zComp);
}
- modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
- itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
+ modelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+ itModelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -1072,7 +1113,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// Release bar shader
m_barShader->release();
}
+#endif
+#if 0
// Handle zoom activation and label drawing
if (!barSelectionFound) {
// We have no ownership, don't delete. Just NULL the pointer.
@@ -1215,11 +1258,11 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// Release label shader
m_labelShader->release();
#endif
-#endif
}
void Scatter3DRenderer::requestSelectionAtPoint(const QPoint &point)
{
+ //qDebug() << __FUNCTION__;
QMutexLocker locker(&m_mutex);
m_selectionPointRequest.setX(point.x());
m_selectionPointRequest.setY(point.y());
@@ -1228,6 +1271,7 @@ void Scatter3DRenderer::requestSelectionAtPoint(const QPoint &point)
void Scatter3DRenderer::handleResize()
{
+ //qDebug() << __FUNCTION__;
if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
return;
qDebug() << "Scatter3DRenderer::resizeEvent " << m_cachedBoundingRect.width() << "x" <<m_cachedBoundingRect.height();
@@ -1254,6 +1298,7 @@ void Scatter3DRenderer::handleResize()
void Scatter3DRenderer::updateBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
{
+ //qDebug() << __FUNCTION__;
m_cachedBarThickness = thickness;
if (relative) {
m_cachedBarSpacing.setWidth((thickness.width() * 2) * (spacing.width() + 1.0f));
@@ -1268,12 +1313,14 @@ void Scatter3DRenderer::updateBarSpecs(QSizeF thickness, QSizeF spacing, bool re
void Scatter3DRenderer::updateMeshFileName(const QString &objFileName)
{
+ //qDebug() << __FUNCTION__;
m_cachedObjFile = objFileName;
loadBarMesh();
}
void Scatter3DRenderer::updateTheme(Theme theme)
{
+ //qDebug() << __FUNCTION__;
m_cachedTheme.setFromTheme(theme);
m_drawer->setTheme(m_cachedTheme);
@@ -1309,28 +1356,33 @@ void Scatter3DRenderer::updateTheme(Theme theme)
void Scatter3DRenderer::updateSelectionMode(SelectionMode mode)
{
+ //qDebug() << __FUNCTION__;
m_cachedSelectionMode = mode;
}
void Scatter3DRenderer::updateFont(const QFont &font)
{
+ //qDebug() << __FUNCTION__;
m_cachedFont = font;
m_drawer->setFont(font);
}
void Scatter3DRenderer::updateLabelTransparency(LabelTransparency transparency)
{
+ //qDebug() << __FUNCTION__;
m_cachedLabelTransparency = transparency;
m_drawer->setTransparency(transparency);
}
void Scatter3DRenderer::updateGridEnabled(bool enable)
{
+ //qDebug() << __FUNCTION__;
m_cachedIsGridEnabled = enable;
}
void Scatter3DRenderer::updateBackgroundEnabled(bool enable)
{
+ //qDebug() << __FUNCTION__;
if (m_cachedIsBackgroundEnabled != enable) {
m_cachedIsBackgroundEnabled = enable;
// Load changed bar type
@@ -1397,6 +1449,7 @@ void Scatter3DRenderer::updateShadowQuality(ShadowQuality quality)
void Scatter3DRenderer::updateTickCount(GLint tickCount, GLfloat step, GLfloat minimum)
{
+ //qDebug() << __FUNCTION__;
m_tickCount = tickCount;
m_tickStep = step;
if (tickCount > 0 && step > 0) {
@@ -1408,29 +1461,33 @@ void Scatter3DRenderer::updateTickCount(GLint tickCount, GLfloat step, GLfloat m
void Scatter3DRenderer::updateBoundingRect(const QRect boundingRect)
{
+ //qDebug() << __FUNCTION__;
m_cachedBoundingRect = boundingRect;
handleResize();
}
void Scatter3DRenderer::updatePosition(const QRect boundingRect)
{
+ //qDebug() << __FUNCTION__;
m_cachedBoundingRect = boundingRect;
}
void Scatter3DRenderer::loadBarMesh()
{
+ //qDebug() << __FUNCTION__;
QString objectFileName = m_cachedObjFile;
if (m_barObj)
delete m_barObj;
// If background is disabled, load full version of bar mesh
- if (!m_cachedIsBackgroundEnabled)
- objectFileName.append(QStringLiteral("Full"));
+ // if (!m_cachedIsBackgroundEnabled)
+ // objectFileName.append(QStringLiteral("Full"));
m_barObj = new ObjectHelper(objectFileName);
m_barObj->load();
}
void Scatter3DRenderer::loadBackgroundMesh()
{
+ //qDebug() << __FUNCTION__;
if (m_backgroundObj)
delete m_backgroundObj;
m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
@@ -1439,6 +1496,7 @@ void Scatter3DRenderer::loadBackgroundMesh()
void Scatter3DRenderer::loadGridLineMesh()
{
+ //qDebug() << __FUNCTION__;
if (m_gridLineObj)
delete m_gridLineObj;
m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
@@ -1447,6 +1505,7 @@ void Scatter3DRenderer::loadGridLineMesh()
void Scatter3DRenderer::loadLabelMesh()
{
+ //qDebug() << __FUNCTION__;
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
@@ -1455,53 +1514,55 @@ void Scatter3DRenderer::loadLabelMesh()
void Scatter3DRenderer::updateTextures()
{
+ //qDebug() << __FUNCTION__;
// Drawer has changed; this flag needs to be checked when checking if we need to update labels
m_updateLabels = true;
}
void Scatter3DRenderer::calculateSceneScalingFactors(const QRect &areaRect)
{
+ //qDebug() << __FUNCTION__;
m_areaSize = areaRect.size();
// Calculate scaling factor so that we can be sure the whole area fits to positive z space
- if (zComp > 1.0f)
- m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()) / zComp;
- else
- m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
- //qDebug() << "scaleFactor" << m_scaleFactor;
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
+ qDebug() << "scaleFactor" << m_scaleFactor;
}
void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item)
{
- // TODO: We need to calculate y -translation here as well, based on value.
+ //qDebug() << __FUNCTION__;
+
// Origin should be in the center of scene, ie. both positive and negative values are drawn
// above background
- // We need to convert position (which is in coordinates), to translation (which has origin in the center and is scaled)
- // -> move pos(center, center) to trans(0, 0) and pos(0, 0) to trans(left, top)
- GLfloat xTrans = 2.0f * (item.scatterPosition().x() - (m_areaSize.width() / 2.0f))
- / m_scaleFactor;
- GLfloat zTrans = 2.0f * (item.scatterPosition().y() - (m_areaSize.height() / 2.0f))
- / m_scaleFactor;
+ // We need to normalize translation based on given area (if given)
+
+ GLfloat xTrans = aspectRatio * item.scatterPosition().x()
+ / (m_areaSize.width() * m_scaleFactor);
+ GLfloat zTrans = aspectRatio * item.scatterPosition().y()
+ / (m_areaSize.height() * m_scaleFactor);
+ GLfloat yTrans = item.value() / (m_tickCount * m_tickStep * m_scaleFactor);
//qDebug() << "x, y" << item.mapPosition().x() << item.mapPosition().y();
- item.setTranslation(QVector3D(xTrans, 0.0f, zTrans + zComp));
- //qDebug() << item.translation();
+ item.setTranslation(QVector3D(xTrans, yTrans, zTrans + zComp));
+ //qDebug() << item.translation() << m_heightNormalizer;
}
void Scatter3DRenderer::calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits)
{
- // TODO: How does origin being in the center of the scene affect this?
+ //qDebug() << __FUNCTION__;
// 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;
+ //qDebug() << limits << m_yAdjustment;
}
Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint bar,
const QVector3D &selection)
{
+ //qDebug() << __FUNCTION__;
GLubyte barIdxRed = 0;
GLubyte barIdxGreen = 0;
GLubyte barIdxBlue = 0;
- //static QVector3D prevSel = selection; // TODO: For debugging
+ static QVector3D prevSel = selection; // TODO: For debugging
Scatter3DController::SelectionType isSelectedType = Scatter3DController::SelectionNone;
if (selection == selectionSkipColor)
@@ -1521,10 +1582,10 @@ Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint bar,
QVector3D current = QVector3D(barIdxRed, barIdxGreen, barIdxBlue);
// TODO: For debugging
- //if (selection != prevSel) {
- // qDebug() << selection.x() << selection .y() << selection.z();
- // prevSel = selection;
- //}
+ if (selection != prevSel) {
+ qDebug() << selection.x() << selection .y() << selection.z();
+ prevSel = selection;
+ }
if (current == selection)
isSelectedType = Scatter3DController::SelectionBar;
@@ -1549,17 +1610,20 @@ Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint bar,
void Scatter3DRenderer::updateZoomLevel(int newZoomLevel)
{
+ //qDebug() << __FUNCTION__;
m_cachedZoomLevel = newZoomLevel;
}
QRect Scatter3DRenderer::mainViewPort()
{
+ //qDebug() << __FUNCTION__;
return m_mainViewPort;
}
void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
{
+ //qDebug() << __FUNCTION__;
if (m_barShader)
delete m_barShader;
m_barShader = new ShaderHelper(this, vertexShader, fragmentShader);
@@ -1568,6 +1632,7 @@ void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &
void Scatter3DRenderer::initSelectionShader()
{
+ //qDebug() << __FUNCTION__;
if (m_selectionShader)
delete m_selectionShader;
m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
@@ -1577,6 +1642,7 @@ void Scatter3DRenderer::initSelectionShader()
void Scatter3DRenderer::initSelectionBuffer()
{
+ //qDebug() << __FUNCTION__;
if (m_selectionTexture)
m_textureHelper->deleteTexture(&m_selectionTexture);
@@ -1588,6 +1654,7 @@ void Scatter3DRenderer::initSelectionBuffer()
#if !defined(QT_OPENGL_ES_2)
void Scatter3DRenderer::initDepthShader()
{
+ //qDebug() << __FUNCTION__;
if (m_depthShader)
delete m_depthShader;
m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
@@ -1597,6 +1664,7 @@ void Scatter3DRenderer::initDepthShader()
void Scatter3DRenderer::updateDepthBuffer()
{
+ //qDebug() << __FUNCTION__;
if (m_depthTexture) {
m_textureHelper->deleteTexture(&m_depthTexture);
m_depthTexture = 0;
@@ -1632,6 +1700,7 @@ void Scatter3DRenderer::updateDepthBuffer()
void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
const QString &fragmentShader)
{
+ //qDebug() << __FUNCTION__;
if (m_backgroundShader)
delete m_backgroundShader;
m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
@@ -1640,6 +1709,7 @@ void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
void Scatter3DRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
{
+ //qDebug() << __FUNCTION__;
if (m_labelShader)
delete m_labelShader;
m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
diff --git a/src/datavis3d/global/qdatavis3dnamespace.h b/src/datavis3d/global/qdatavis3dnamespace.h
index 1155ef58..d3fc41a2 100644
--- a/src/datavis3d/global/qdatavis3dnamespace.h
+++ b/src/datavis3d/global/qdatavis3dnamespace.h
@@ -53,7 +53,8 @@ enum BarStyle {
Cones,
Cylinders,
BevelBars,
- Spheres
+ Spheres,
+ Dots
};
enum CameraPreset {