diff options
author | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-08-05 08:58:37 +0300 |
---|---|---|
committer | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-08-05 10:59:59 +0300 |
commit | bfc8e5e40eafea00bdc481a663e229a23dc8f83b (patch) | |
tree | 58487c4e8cfe60ada257e4e3e2aae3ec1b05586a | |
parent | 2b3dde773f730c7b32268751de42ca8724785553 (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.pro | 3 | ||||
-rw-r--r-- | examples/scatterchart/doc/src/scatterchart.qdoc | 38 | ||||
-rw-r--r-- | examples/scatterchart/main.cpp | 227 | ||||
-rw-r--r-- | examples/scatterchart/scatterchart.cpp | 287 | ||||
-rw-r--r-- | examples/scatterchart/scatterchart.h | 88 | ||||
-rw-r--r-- | examples/scatterchart/scatterchart.pro | 10 | ||||
-rw-r--r-- | src/datavis3d/doc/src/qtdatavis3d-index.qdoc | 1 | ||||
-rw-r--r-- | src/datavis3d/engine/engine.qrc | 2 | ||||
-rw-r--r-- | src/datavis3d/engine/meshes/scatterdot.obj | 28 | ||||
-rw-r--r-- | src/datavis3d/engine/meshes/scatterdotFlat.obj | 28 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3dcontroller.cpp | 29 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3drenderer.cpp | 282 | ||||
-rw-r--r-- | src/datavis3d/global/qdatavis3dnamespace.h | 3 |
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 { |