diff options
-rw-r--r-- | examples/examples.pro | 1 | ||||
-rw-r--r-- | examples/qmlscatter/doc/src/qmlscatter.qdoc | 38 | ||||
-rw-r--r-- | examples/qmlscatter/main.cpp | 47 | ||||
-rw-r--r-- | examples/qmlscatter/qml/qmlscatter/main.qml | 124 | ||||
-rw-r--r-- | examples/qmlscatter/qmlscatter.desktop | 11 | ||||
-rw-r--r-- | examples/qmlscatter/qmlscatter.pro | 23 | ||||
-rw-r--r-- | examples/qmlscatter/qmlscatter.qrc | 5 | ||||
-rw-r--r-- | examples/qmlscatter/qmlscatter64.png | bin | 0 -> 3400 bytes | |||
-rw-r--r-- | examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp | 81 | ||||
-rw-r--r-- | examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h | 33 | ||||
-rw-r--r-- | examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri | 180 | ||||
-rw-r--r-- | src/datavis3d/doc/src/qtdatavis3d-index.qdoc | 1 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3drenderer.cpp | 121 | ||||
-rw-r--r-- | src/datavis3d/engine/scatter3drenderer_p.h | 4 |
14 files changed, 609 insertions, 60 deletions
diff --git a/examples/examples.pro b/examples/examples.pro index 636d7022..3541c7ad 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -5,6 +5,7 @@ SUBDIRS += barchart \ mapdata \ qmlbarchart \ qmlmaps \ + qmlscatter \ surfacechart \ scatterchart diff --git a/examples/qmlscatter/doc/src/qmlscatter.qdoc b/examples/qmlscatter/doc/src/qmlscatter.qdoc new file mode 100644 index 00000000..b38111fc --- /dev/null +++ b/examples/qmlscatter/doc/src/qmlscatter.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 qmlscatter + \title Qt Quick 2 Scatter Example + + The Qt Quick 2 scatter example shows how to make a simple scatter chart visualization using + Q3DScatter using Qt Quick 2. + + \image qmlscatter-example.png + + TODO +*/ diff --git a/examples/qmlscatter/main.cpp b/examples/qmlscatter/main.cpp new file mode 100644 index 00000000..877df783 --- /dev/null +++ b/examples/qmlscatter/main.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include "qtquick2applicationviewer.h" +#ifdef Q_OS_ANDROID +#include <QDir> +#include <QQmlEngine> +#endif +#include <QDebug> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QtQuick2ApplicationViewer viewer; +#ifdef Q_OS_ANDROID + viewer.addImportPath(QString::fromLatin1("assets:/qml")); + viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(), + QString::fromLatin1("lib"))); +#else + viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), + QString::fromLatin1("qml"))); +#endif + viewer.setSource(QUrl("qrc:/qml/main.qml")); + viewer.setResizeMode(QQuickView::SizeRootObjectToView); + viewer.show(); + + return app.exec(); +} diff --git a/examples/qmlscatter/qml/qmlscatter/main.qml b/examples/qmlscatter/qml/qmlscatter/main.qml new file mode 100644 index 00000000..7b3aa594 --- /dev/null +++ b/examples/qmlscatter/qml/qmlscatter/main.qml @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import com.digia.QtDataVis3D 1.0 + +Item { + id: mainview + width: 800 + height: 500 + visible: true + + Item { + id: dataView + width: parent.width + height: parent.height - shadowToggle.height + anchors.bottom: parent.bottom + + ScatterDataMapping { + id: scatterMapping + xPosRole: "xPos" + yPosRole: "yPos" + zPosRole: "zPos" + } + + ListModel { + id: dataModel +// ListElement{ xPos: -100.0; yPos: 490.0; zPos: -50.0 } +// ListElement{ xPos: 100.0; yPos: 105.0; zPos: 50.0 } +// ListElement{ xPos: 50.0; yPos: 465.0; zPos: -50.0 } +// ListElement{ xPos: -50.0; yPos: 225.0; zPos: 50.0 } + ListElement{ xPos: -1.0; yPos: 4.3; zPos: -0.5 } + ListElement{ xPos: 1.0; yPos: 0.105; zPos: 0.5 } + ListElement{ xPos: 0.5; yPos: -4.65; zPos: -0.5 } + ListElement{ xPos: -0.5; yPos: 0.225; zPos: 0.5 } + ListElement{ xPos: 0.0; yPos: 0.0; zPos: 0.0 } + ListElement{ xPos: 0.0; yPos: 2.0; zPos: 0.0 } + ListElement{ xPos: 0.0; yPos: -2.0; zPos: 0.0 } + ListElement{ xPos: -1.0; yPos: 4.9; zPos: -1.0 } + ListElement{ xPos: 1.0; yPos: 4.9; zPos: -1.0 } + ListElement{ xPos: -1.0; yPos: 4.9; zPos: 1.0 } + ListElement{ xPos: 1.0; yPos: 4.9; zPos: 1.0 } + ListElement{ xPos: -1.0; yPos: -4.9; zPos: -1.0 } + ListElement{ xPos: 1.0; yPos: -4.9; zPos: -1.0 } + ListElement{ xPos: -1.0; yPos: -4.9; zPos: 1.0 } + ListElement{ xPos: 1.0; yPos: -4.9; zPos: 1.0 } + } + + Scatter3D { + id: testscatter + width: dataView.width + height: dataView.height + fontSize: 300.0 + mapping: scatterMapping + + Component.onCompleted: { + console.log("testscatter complete"); +// console.log(testimage); +// console.log(testimage.sourceSize); +// setBarSpecs(Qt.vector3d(10.0, 10.0, 10.0)); +// setAreaSpecs(Qt.rect(0, 0, testimage.sourceSize.width, testimage.sourceSize.height), +// testimage); +// //setImage(testimage); +// setImage(":/images/floorplan.jpg"); + setTickCount(10, 0.5, -5.0); + shadowQuality = Scatter3D.ShadowNone + selectionMode = Scatter3D.ModeBar + labelTransparency = Scatter3D.TransparencyNoBackground//.TransparencyFromTheme + data = dataModel + } + } + } + + Component.onCompleted: { + console.log("mainview complete"); + } + + Rectangle { + id: shadowToggle + color: "#FFFFFF" + x: 0 + y: 0 + width: parent.width + height: 60 + + TextArea { + id: buttonText + text: "Toggle Shadows" + anchors.fill: parent + textColor: "#000000" + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (testscatter.shadowQuality === Scatter3D.ShadowNone) { + testscatter.shadowQuality = Scatter3D.ShadowLow; + buttonText.textColor = "#999999"; + } else { + testscatter.shadowQuality = Scatter3D.ShadowNone; + buttonText.textColor = "#000000"; + } + } + } + } +} diff --git a/examples/qmlscatter/qmlscatter.desktop b/examples/qmlscatter/qmlscatter.desktop new file mode 100644 index 00000000..0f9e5498 --- /dev/null +++ b/examples/qmlscatter/qmlscatter.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Type=Application +Terminal=false +Name=qmlscatter +Exec=/opt/qmlscatter/bin/qmlscatter +Icon=qmlscatter64 +X-Window-Icon= +X-HildonDesk-ShowInToolbar=true +X-Osso-Type=application/x-executable diff --git a/examples/qmlscatter/qmlscatter.pro b/examples/qmlscatter/qmlscatter.pro new file mode 100644 index 00000000..6f89fbae --- /dev/null +++ b/examples/qmlscatter/qmlscatter.pro @@ -0,0 +1,23 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +# Add more folders to ship with the application, here +folder_01.source = qml/qmlscatter +folder_01.target = qml +DEPLOYMENTFOLDERS = folder_01 + +# Additional import path used to resolve QML modules in Creator's code model +QML_IMPORT_PATH = + +# The .cpp file which was generated for your project. Feel free to hack it. +SOURCES += main.cpp + +# Installation path +# target.path = + +# Please do not modify the following two lines. Required for deployment. +include(qtquick2applicationviewer/qtquick2applicationviewer.pri) +qtcAddDeployment() + +RESOURCES += qmlscatter.qrc diff --git a/examples/qmlscatter/qmlscatter.qrc b/examples/qmlscatter/qmlscatter.qrc new file mode 100644 index 00000000..62f5931b --- /dev/null +++ b/examples/qmlscatter/qmlscatter.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/qml"> + <file alias="main.qml">qml/qmlscatter/main.qml</file> + </qresource> +</RCC> diff --git a/examples/qmlscatter/qmlscatter64.png b/examples/qmlscatter/qmlscatter64.png Binary files differnew file mode 100644 index 00000000..707d5c4e --- /dev/null +++ b/examples/qmlscatter/qmlscatter64.png diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp new file mode 100644 index 00000000..10709d7a --- /dev/null +++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp @@ -0,0 +1,81 @@ +// checksum 0x4f6f version 0x90005 +/* + This file was generated by the Qt Quick 2 Application wizard of Qt Creator. + QtQuick2ApplicationViewer is a convenience class containing mobile device specific + code such as screen orientation handling. Also QML paths and debugging are + handled here. + It is recommended not to modify this file, since newer versions of Qt Creator + may offer an updated version of it. +*/ + +#include "qtquick2applicationviewer.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> +#include <QtQml/QQmlEngine> + +class QtQuick2ApplicationViewerPrivate +{ + QString mainQmlFile; + friend class QtQuick2ApplicationViewer; + static QString adjustPath(const QString &path); +}; + +QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path) +{ +#if defined(Q_OS_MAC) + if (!QDir::isAbsolutePath(path)) + return QString::fromLatin1("%1/../Resources/%2") + .arg(QCoreApplication::applicationDirPath(), path); +#elif defined(Q_OS_BLACKBERRY) + if (!QDir::isAbsolutePath(path)) + return QString::fromLatin1("app/native/%1").arg(path); +#elif !defined(Q_OS_ANDROID) + QString pathInInstallDir = + QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path); + if (QFileInfo(pathInInstallDir).exists()) + return pathInInstallDir; + pathInInstallDir = + QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path); + if (QFileInfo(pathInInstallDir).exists()) + return pathInInstallDir; +#endif + return path; +} + +QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent) + : QQuickView(parent) + , d(new QtQuick2ApplicationViewerPrivate()) +{ + connect(engine(), SIGNAL(quit()), SLOT(close())); + setResizeMode(QQuickView::SizeRootObjectToView); +} + +QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer() +{ + delete d; +} + +void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file) +{ + d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file); +#ifdef Q_OS_ANDROID + setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile)); +#else + setSource(QUrl::fromLocalFile(d->mainQmlFile)); +#endif +} + +void QtQuick2ApplicationViewer::addImportPath(const QString &path) +{ + engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path)); +} + +void QtQuick2ApplicationViewer::showExpanded() +{ +#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX) + showFullScreen(); +#else + show(); +#endif +} diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h new file mode 100644 index 00000000..cf66f140 --- /dev/null +++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h @@ -0,0 +1,33 @@ +// checksum 0xfde6 version 0x90005 +/* + This file was generated by the Qt Quick 2 Application wizard of Qt Creator. + QtQuick2ApplicationViewer is a convenience class containing mobile device specific + code such as screen orientation handling. Also QML paths and debugging are + handled here. + It is recommended not to modify this file, since newer versions of Qt Creator + may offer an updated version of it. +*/ + +#ifndef QTQUICK2APPLICATIONVIEWER_H +#define QTQUICK2APPLICATIONVIEWER_H + +#include <QtQuick/QQuickView> + +class QtQuick2ApplicationViewer : public QQuickView +{ + Q_OBJECT + +public: + explicit QtQuick2ApplicationViewer(QWindow *parent = 0); + virtual ~QtQuick2ApplicationViewer(); + + void setMainQmlFile(const QString &file); + void addImportPath(const QString &path); + + void showExpanded(); + +private: + class QtQuick2ApplicationViewerPrivate *d; +}; + +#endif // QTQUICK2APPLICATIONVIEWER_H diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri new file mode 100644 index 00000000..e5f7990f --- /dev/null +++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri @@ -0,0 +1,180 @@ +# checksum 0x7b0d version 0x90005 +# This file was generated by the Qt Quick 2 Application wizard of Qt Creator. +# The code below adds the QtQuick2ApplicationViewer to the project and handles +# the activation of QML debugging. +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +QT += qml quick + +SOURCES += $$PWD/qtquick2applicationviewer.cpp +HEADERS += $$PWD/qtquick2applicationviewer.h +INCLUDEPATH += $$PWD +# This file was generated by an application wizard of Qt Creator. +# The code below handles deployment to Android and Maemo, aswell as copying +# of the application data to shadow build directories on desktop. +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +defineTest(qtcAddDeployment) { +for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + greaterThan(QT_MAJOR_VERSION, 4) { + itemsources = $${item}.files + } else { + itemsources = $${item}.sources + } + $$itemsources = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath= $$eval($${deploymentfolder}.target) + export($$itemsources) + export($$itempath) + DEPLOYMENT += $$item +} + +MAINPROFILEPWD = $$PWD + +android-no-sdk { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + target.path = /data/user/qt + + export(target.path) + INSTALLS += target +} else:android { + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = /assets/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + + export(target.path) + INSTALLS += target +} else:win32 { + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, /, \\) + sourcePathSegments = $$split(source, \\) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments) + target = $$replace(target, /, \\) + target ~= s,\\\\\\.?\\\\,\\, + !isEqual(source,$$target) { + !isEmpty(copyCommand):copyCommand += && + isEqual(QMAKE_DIR_SEP, \\) { + copyCommand += $(COPY_DIR) \"$$source\" \"$$target\" + } else { + source = $$replace(source, \\\\, /) + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + target = $$replace(target, \\\\, /) + copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\" + } + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } +} else:unix { + maemo5 { + desktopfile.files = $${TARGET}.desktop + desktopfile.path = /usr/share/applications/hildon + icon.files = $${TARGET}64.png + icon.path = /usr/share/icons/hicolor/64x64/apps + } else:!isEmpty(MEEGO_VERSION_MAJOR) { + desktopfile.files = $${TARGET}_harmattan.desktop + desktopfile.path = /usr/share/applications + icon.files = $${TARGET}80.png + icon.path = /usr/share/icons/hicolor/80x80/apps + } else { # Assumed to be a Desktop Unix + copyCommand = + for(deploymentfolder, DEPLOYMENTFOLDERS) { + source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) + source = $$replace(source, \\\\, /) + macx { + target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target) + } else { + target = $$OUT_PWD/$$eval($${deploymentfolder}.target) + } + target = $$replace(target, \\\\, /) + sourcePathSegments = $$split(source, /) + targetFullPath = $$target/$$last(sourcePathSegments) + targetFullPath ~= s,/\\.?/,/, + !isEqual(source,$$targetFullPath) { + !isEmpty(copyCommand):copyCommand += && + copyCommand += $(MKDIR) \"$$target\" + copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\" + } + } + !isEmpty(copyCommand) { + copyCommand = @echo Copying application data... && $$copyCommand + copydeploymentfolders.commands = $$copyCommand + first.depends = $(first) copydeploymentfolders + export(first.depends) + export(copydeploymentfolders.commands) + QMAKE_EXTRA_TARGETS += first copydeploymentfolders + } + } + !isEmpty(target.path) { + installPrefix = $${target.path} + } else { + installPrefix = /opt/$${TARGET} + } + for(deploymentfolder, DEPLOYMENTFOLDERS) { + item = item$${deploymentfolder} + itemfiles = $${item}.files + $$itemfiles = $$eval($${deploymentfolder}.source) + itempath = $${item}.path + $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target) + export($$itemfiles) + export($$itempath) + INSTALLS += $$item + } + + !isEmpty(desktopfile.path) { + export(icon.files) + export(icon.path) + export(desktopfile.files) + export(desktopfile.path) + INSTALLS += icon desktopfile + } + + isEmpty(target.path) { + target.path = $${installPrefix}/bin + export(target.path) + } + INSTALLS += target +} + +export (ICON) +export (INSTALLS) +export (DEPLOYMENT) +export (LIBS) +export (QMAKE_EXTRA_TARGETS) +} diff --git a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc index 8a6f1abe..384b128e 100644 --- a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc +++ b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc @@ -62,6 +62,7 @@ \li \l{Mapdata Example} \li \l{Qt Quick 2 Barchart Example} \li \l{Qt Quick 2 Maps Example} + \li \l{Qt Quick 2 Scatter Example} \li \l{Rainfall Example} \li \l{Scatter Chart Example} \li \l{Spectrum Example} diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp index 33a55a9f..24dadd83 100644 --- a/src/datavis3d/engine/scatter3drenderer.cpp +++ b/src/datavis3d/engine/scatter3drenderer.cpp @@ -107,6 +107,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_scaleFactor(0), m_selection(selectionSkipColor), m_areaSize(QSizeF(2.0f, 2.0f)), + m_autoAdjust(true), m_hasHeightAdjustmentChanged(true), m_dataProxy(0), m_valueUpdateNeeded(false) @@ -163,13 +164,12 @@ void Scatter3DRenderer::initializePreOpenGL() // TODO Should all this initial setup be mutexed? updateSelectionMode(m_controller->selectionMode()); - //updateLimits(m_controller->limits()); updateZoomLevel(m_controller->zoomLevel()); updateMeshFileName(m_controller->objFile()); updateGridEnabled(m_controller->gridEnabled()); updateBackgroundEnabled(m_controller->backgroundEnabled()); - calculateSceneScalingFactors(); + calculateSceneScalingFactors(QRect(0, 0, m_areaSize.width(), m_areaSize.height())); } @@ -267,6 +267,9 @@ void Scatter3DRenderer::render(QScatterDataProxy *dataProxy, m_renderItemArray[i].setPosition(dataArray.at(i).position()); //m_renderItemArray[i].setHeight(value / m_heightNormalizer); //m_renderItemArray[i].setItemLabel(dataArray.at(i).label()); + updateLimits(dataArray.at(i).position()); + } + for (int i = 0; i < dataSize ; i++) { calculateTranslation(m_renderItemArray[i]); m_renderItemArray[i].setRenderer(this); } @@ -741,13 +744,13 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, modelMatrix.scale( QVector3D( (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor, - backgroundMargin / m_scaleFactor, + backgroundMargin, (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor)); modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); itModelMatrix.scale( QVector3D( (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor, - backgroundMargin / m_scaleFactor, + backgroundMargin, (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor)); #ifdef SHOW_DEPTH_TEXTURE_SCENE @@ -813,19 +816,18 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme.m_ambientStrength); // Floor lines: rows - GLfloat lineStep = m_tickStep * 2.0f; // TODO: For now, multiply by two to keep the tick count correct (as we start from negative) - GLfloat startLine = -m_heightNormalizer; + GLfloat lineStep = (2.0f * m_scaleFactor * aspectRatio) / m_tickCount; + GLfloat startLine = -m_scaleFactor * aspectRatio; - for (GLfloat linePos = startLine; linePos <= m_heightNormalizer; linePos += lineStep) { + for (GLfloat linePos = startLine; linePos <= -startLine; linePos += lineStep) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate( - 0.0f, - -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor, - (aspectRatio * linePos) / (m_heightNormalizer * m_scaleFactor) + zComp); + modelMatrix.translate(0.0f, + -m_yAdjustment - backgroundMargin, + linePos / m_scaleFactor + zComp); modelMatrix.scale( QVector3D( (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor, @@ -866,16 +868,15 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } // Floor lines: columns - for (GLfloat linePos = startLine; linePos <= m_heightNormalizer; linePos += lineStep) { + for (GLfloat linePos = startLine; linePos <= -startLine; linePos += lineStep) { QMatrix4x4 modelMatrix; QMatrix4x4 MVPMatrix; QMatrix4x4 depthMVPMatrix; QMatrix4x4 itModelMatrix; - modelMatrix.translate( - (aspectRatio * linePos) / (m_heightNormalizer * m_scaleFactor), - -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor, - zComp); + modelMatrix.translate(linePos / m_scaleFactor, + -m_yAdjustment - backgroundMargin, + zComp); modelMatrix.scale( QVector3D( gridLineWidth, gridLineWidth, @@ -916,7 +917,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } // Wall lines: back wall - for (GLfloat linePos = startLine; linePos <= m_heightNormalizer; linePos += lineStep) { + lineStep = 2.0f * m_tickStep; + startLine = -m_heightNormalizer; + + for (GLfloat linePos = startLine; linePos <= -startLine; linePos += lineStep) { GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor; QMatrix4x4 modelMatrix; @@ -927,10 +931,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, if (!m_zFlipped) lineZTrans = -lineZTrans; - modelMatrix.translate( - 0.0f, - linePos / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment, - lineZTrans + zComp); + modelMatrix.translate(0.0f, + linePos / m_heightNormalizer - m_yAdjustment, + lineZTrans + zComp); modelMatrix.scale( QVector3D( (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor), @@ -971,7 +974,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } // Wall lines: side wall - for (GLfloat linePos = startLine; linePos <= m_heightNormalizer; linePos += lineStep) { + for (GLfloat linePos = startLine; linePos <= -startLine; linePos += lineStep) { GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor; QMatrix4x4 modelMatrix; @@ -982,10 +985,9 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, if (!m_xFlipped) lineXTrans = -lineXTrans; - modelMatrix.translate( - lineXTrans, - linePos / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment, - zComp); + modelMatrix.translate(lineXTrans, + linePos / m_heightNormalizer - m_yAdjustment, + zComp); modelMatrix.scale( QVector3D( gridLineWidth, gridLineWidth, @@ -1096,10 +1098,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } // Z Labels - GLfloat posStep = m_tickStep * 2.0f; // TODO: For now, multiply by two to keep the tick count correct (as we start from negative) - GLfloat startPos = -m_heightNormalizer; + GLfloat posStep = (2.0f * m_scaleFactor * aspectRatio) / m_tickCount; + GLfloat startPos = -m_scaleFactor * aspectRatio; int labelNbr = 0; - for (GLfloat labelPos = startPos; labelPos <= m_heightNormalizer; labelPos += posStep) { + for (GLfloat labelPos = startPos; labelPos <= -startPos; labelPos += posStep) { if (m_axisCacheX.labelItems().size() > labelNbr) { GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor; @@ -1115,8 +1117,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } QVector3D labelTrans = QVector3D( labelXTrans, - -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor, - (aspectRatio * labelPos) / (m_heightNormalizer * m_scaleFactor) + zComp); + -m_yAdjustment - (m_heightNormalizer * backgroundMargin), + labelPos / m_scaleFactor + zComp); // TODO: Try it; draw the label here m_dummyRenderItem.setTranslation(labelTrans); @@ -1134,7 +1136,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, } // X Labels labelNbr = 0; - for (GLfloat labelPos = startPos; labelPos <= m_heightNormalizer; labelPos += posStep) { + for (GLfloat labelPos = startPos; labelPos <= -startPos; labelPos += posStep) { if (m_axisCacheX.labelItems().size() > labelNbr) { GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor; @@ -1149,8 +1151,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, alignment = Qt::AlignRight; } QVector3D labelTrans = QVector3D( - (aspectRatio * labelPos) / (m_heightNormalizer * m_scaleFactor), - -m_yAdjustment - (m_heightNormalizer * backgroundMargin) / m_scaleFactor, + labelPos / m_scaleFactor, + -m_yAdjustment - (m_heightNormalizer * backgroundMargin), labelZTrans + zComp); // TODO: Try it; draw the label here @@ -1168,15 +1170,17 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera, labelNbr++; } // Y Labels + posStep = 2.0f * m_tickStep; + startPos = -m_heightNormalizer; labelNbr = 0; - for (GLfloat labelPos = startPos; labelPos <= m_heightNormalizer; labelPos += posStep) { + for (GLfloat labelPos = startPos; labelPos <= -startPos; labelPos += posStep) { // TODO: Test with x labels if (m_axisCacheX.labelItems().size() > labelNbr) { GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor; GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor; - GLfloat labelYTrans = labelPos / (m_heightNormalizer * m_scaleFactor) - m_yAdjustment; + GLfloat labelYTrans = labelPos / m_heightNormalizer - m_yAdjustment; GLfloat rotLabelX = 0.0f; GLfloat rotLabelY = -90.0f; GLfloat rotLabelZ = 0.0f; @@ -1347,6 +1351,7 @@ void Scatter3DRenderer::updateTickCount(GLint tickCount, GLfloat step, GLfloat m m_tickCount = tickCount; m_tickStep = step; if (tickCount > 0 && step > 0) { + m_autoAdjust = false; m_heightNormalizer = tickCount * step; calculateHeightAdjustment(QPair<float, float>(minimum, m_heightNormalizer)); m_valueUpdateNeeded = true; @@ -1403,9 +1408,11 @@ void Scatter3DRenderer::updateTextures() 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 - m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); + if (!m_autoAdjust) { + m_areaSize = areaRect.size(); + // Calculate scaling factor so that we can be sure the whole area fits to positive z space + m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); + } qDebug() << "scaleFactor" << m_scaleFactor; } @@ -1418,14 +1425,14 @@ void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item) // We need to normalize translation based on given area (if given) - GLfloat xTrans = aspectRatio * item.position().x() - / (m_areaSize.width() * m_scaleFactor); - GLfloat zTrans = aspectRatio * item.position().z() - / (m_areaSize.height() * m_scaleFactor); - GLfloat yTrans = item.position().y() / (m_tickCount * m_tickStep * m_scaleFactor); - // TODO: Do we need to update m_heightNormalizer here based on item.position().y()? (can updateLimits be used?) - // TODO: Test if yTrans is always -1.0 ... 1.0 - //qDebug() << "x, y" << item.mapPosition().x() << item.mapPosition().y(); + // GLfloat xTrans = aspectRatio * item.position().x() + // / (m_areaSize.width() * m_scaleFactor); + // GLfloat zTrans = aspectRatio * item.position().z() + // / (m_areaSize.height() * m_scaleFactor); + // GLfloat yTrans = item.position().y() / (m_tickCount * m_tickStep * m_heightNormalizer); + GLfloat xTrans = (aspectRatio * 2.0f * item.position().x()) / m_scaleFactor; + GLfloat zTrans = (aspectRatio * 2.0f * item.position().z()) / m_scaleFactor; + GLfloat yTrans = item.position().y() / m_heightNormalizer; item.setTranslation(QVector3D(xTrans, yTrans, zTrans + zComp)); //qDebug() << item.translation() << m_heightNormalizer; } @@ -1476,20 +1483,18 @@ Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint bar, return isSelectedType; } -// TODO: Do we need this for autoscaling? -/*void Scatter3DRenderer::updateLimits(QPair<GLfloat, GLfloat> limits) +void Scatter3DRenderer::updateLimits(const QVector3D &limits) { - m_limits.first = limits.first; - m_limits.second = limits.second; - - // Don't auto-adjust height if tick count is set - if (m_tickCount == 0) { - m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first)); - calculateHeightAdjustment(limits); - m_valueUpdateNeeded = true; + if (m_autoAdjust) { + m_heightNormalizer = (GLfloat)qMax((qreal)m_heightNormalizer, qFabs(limits.y())); + m_tickStep = m_heightNormalizer / m_tickCount; } + // Auto-adjust these anyway (until axis -based ticks are taken into use) + m_areaSize.setHeight(qMax(m_areaSize.height(), (qreal)limits.z())); + m_areaSize.setWidth(qMax(m_areaSize.width(), (qreal)limits.x())); + m_scaleFactor = qMax(qMax((qreal)m_scaleFactor, m_areaSize.width()), m_areaSize.height()); + qDebug() << m_heightNormalizer << m_areaSize << m_scaleFactor << m_tickStep; } -*/ void Scatter3DRenderer::updateZoomLevel(int newZoomLevel) { diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavis3d/engine/scatter3drenderer_p.h index fa42cd91..10d08981 100644 --- a/src/datavis3d/engine/scatter3drenderer_p.h +++ b/src/datavis3d/engine/scatter3drenderer_p.h @@ -137,8 +137,8 @@ private: QPoint m_selectionPointRequest; bool m_isSelectionPointRequestActive; + bool m_autoAdjust; bool m_hasHeightAdjustmentChanged; - QPair<GLfloat, GLfloat> m_limits; ScatterRenderItem m_dummyRenderItem; QScatterDataProxy *m_dataProxy; // Only valid during render @@ -162,7 +162,7 @@ public: public slots: void updateSelectionMode(SelectionMode newMode); - //void updateLimits(QPair<GLfloat, GLfloat> newLimits); + void updateLimits(const QVector3D &limits); void updateZoomLevel(int newZoomLevel); void updateGridEnabled(bool enable); void updateBackgroundEnabled(bool enable); |