diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-12 09:53:52 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-12 10:31:27 +0300 |
commit | 7f8966b035c9fd73d2cde04521c92892feefc0f9 (patch) | |
tree | 55fee47c70805ff6bd4df1a8cd7693ea34132b27 /src/datavisualization/engine | |
parent | 1262c6562d7264c9fe4caf2f433615348c0f2ef8 (diff) |
Fix Q3DScene caching
Task-number: QTRD-2258
Change-Id: Ifce23dca40566e75398e00975e8b2159b325739e
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Reviewed-by: Pasi Keränen <pasi.keranen@digia.com>
Diffstat (limited to 'src/datavisualization/engine')
18 files changed, 304 insertions, 139 deletions
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 2f3476dc..e560deaf 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -25,7 +25,7 @@ #include "q3dcamera.h" #include "q3dlight.h" #include "qabstractdataproxy_p.h" -#include "qabstract3dinputhandler.h" +#include "qabstract3dinputhandler_p.h" #if defined(Q_OS_ANDROID) #include "qtouch3dinputhandler.h" @@ -62,8 +62,6 @@ Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) : m_theme.useColorTheme(QDataVis::ThemeSystem); // Populate the scene - m_scene->setCamera(new Q3DCamera()); - m_scene->setLight(new Q3DLight()); m_scene->light()->setPosition(defaultLightPos); // Create initial default input handler diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 7e5962cc..4a23a1a5 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -20,8 +20,9 @@ #include "q3dvalueaxis.h" #include "texturehelper_p.h" #include "utils_p.h" -#include "q3dscene.h" -#include "q3dcamera.h" +#include "q3dscene_p.h" +#include "q3dcamera_p.h" +#include "q3dlight_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -39,7 +40,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_cachedSelectionMode(QDataVis::ModeNone), m_cachedIsGridEnabled(false), m_cachedIsBackgroundEnabled(false), - m_cachedScene(0) + m_cachedScene(new Q3DScene()) #ifdef DISPLAY_RENDER_SPEED , m_isFirstFrame(true), m_numFrames(0) @@ -47,6 +48,8 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) { QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); + QObject::connect(this, &Abstract3DRenderer::needRender, m_controller, + &Abstract3DController::needRender, Qt::QueuedConnection); } Abstract3DRenderer::~Abstract3DRenderer() @@ -150,10 +153,10 @@ void Abstract3DRenderer::updateTheme(Theme theme) void Abstract3DRenderer::updateScene(Q3DScene *scene) { - // Make a copy of the scene to renderer's cache. - Q3DScene *newScene = scene->clone(); - delete m_cachedScene; - m_cachedScene = newScene; + // Synchronize the controller scene to that of the renderer, and vice versa. + // Controller scene had priority if both have changed same values. + scene->d_ptr->sync(*m_cachedScene->d_ptr); + m_cachedScene->d_ptr->sync(*scene->d_ptr); } void Abstract3DRenderer::handleShadowQualityChange() diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 49a40209..7925b8ad 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -121,6 +121,9 @@ public: virtual void updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count); virtual void updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientation orientation, const QString &format); +signals: + void needRender(); // Emit this if something in renderer causes need for another render pass. + protected: Abstract3DRenderer(Abstract3DController *controller); diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 6331ee8e..387f8530 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -197,7 +197,8 @@ void Bars3DRenderer::updateScene(Q3DScene *scene) void Bars3DRenderer::render(GLuint defaultFboHandle) { - updateSlicingActive(m_cachedScene->isSlicingActivated()); + bool slicingActivated = m_cachedScene->isSlicingActivated(); + updateSlicingActive(slicingActivated); // Handle GL state setup for FBO buffers and clearing of the render surface Abstract3DRenderer::render(defaultFboHandle); @@ -208,6 +209,11 @@ void Bars3DRenderer::render(GLuint defaultFboHandle) // Draw bars scene drawScene(defaultFboHandle); + + // If slicing has been activated by this render pass, we need another render + if (slicingActivated != m_cachedScene->isSlicingActivated()) + emit needRender(); + } void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, @@ -1344,8 +1350,9 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) m_selectedBar = NULL; if (m_cachedIsSlicingActivated && (m_selection == selectionSkipColor - || QDataVis::InputOnOverview == m_controller->inputState())) + || QDataVis::InputOnOverview == m_controller->inputState())) { m_cachedScene->setSlicingActivated(false); + } } else if (m_cachedSelectionMode >= QDataVis::ModeSliceRow && selectionDirty) { // Activate slice mode m_cachedScene->setSlicingActivated(true); diff --git a/src/datavisualization/engine/q3dbox.h b/src/datavisualization/engine/q3dbox.h index 72d97219..fce6948f 100644 --- a/src/datavisualization/engine/q3dbox.h +++ b/src/datavisualization/engine/q3dbox.h @@ -19,9 +19,9 @@ #ifndef Q3DBOX_H #define Q3DBOX_H -#include "datavisualizationglobal_p.h" - -class QMatrix4x4; +#include <QtDataVisualization/qdatavisualizationenums.h> +#include <QMatrix4x4> +#include <QVector3D> QT_DATAVISUALIZATION_BEGIN_NAMESPACE diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp index 906cd466..4b1ca81f 100644 --- a/src/datavisualization/engine/q3dcamera.cpp +++ b/src/datavisualization/engine/q3dcamera.cpp @@ -63,17 +63,25 @@ void Q3DCamera::copyValuesFrom(const Q3DCamera &source) void Q3DCamera::setRotations(const QPointF &rotation) { - setRotationsPrivate(rotation); - d_ptr->m_activePreset = QDataVis::NoPreset; + d_ptr->setRotations(rotation); + if (d_ptr->m_activePreset != QDataVis::NoPreset) { + d_ptr->m_activePreset = QDataVis::NoPreset; + setDirty(true); + } } void Q3DCamera::setDefaultOrientation(const QVector3D &defaultPosition, const QVector3D &defaultTarget, const QVector3D &defaultUp) { - Q3DObject::setPosition(defaultPosition); - d_ptr->m_target = defaultTarget; - d_ptr->m_up = defaultUp; + if (position() != defaultPosition + || d_ptr->m_target != defaultTarget + || d_ptr->m_up != defaultUp) { + setPosition(defaultPosition); + d_ptr->m_target = defaultTarget; + d_ptr->m_up = defaultUp; + setDirty(true); + } } QPointF Q3DCamera::rotations() const @@ -84,7 +92,10 @@ QPointF Q3DCamera::rotations() const void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix) { - d_ptr->m_viewMatrix = viewMatrix; + if (d_ptr->m_viewMatrix != viewMatrix) { + d_ptr->m_viewMatrix = viewMatrix; + setDirty(true); + } } QMatrix4x4 Q3DCamera::viewMatrix() const @@ -92,7 +103,7 @@ QMatrix4x4 Q3DCamera::viewMatrix() const return d_ptr->m_viewMatrix; } -void Q3DCamera::updateViewMatrix(GLfloat zoomAdjustment) +void Q3DCamera::updateViewMatrix(qreal zoomAdjustment) { bool showUnder = parentScene()->isUnderSideCameraEnabled(); int zoom = zoomLevel() * zoomAdjustment; @@ -136,99 +147,99 @@ void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset) { switch (preset) { case QDataVis::PresetFrontLow: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, 0.0f)); + d_ptr->setRotations(QPointF(0.0f, 0.0f)); break; } case QDataVis::PresetFront: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, 22.5f)); + d_ptr->setRotations(QPointF(0.0f, 22.5f)); break; } case QDataVis::PresetFrontHigh: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, 45.0f)); + d_ptr->setRotations(QPointF(0.0f, 45.0f)); break; } case QDataVis::PresetLeftLow: { - Q3DCamera::setRotationsPrivate(QPointF(90.0f, 0.0f)); + d_ptr->setRotations(QPointF(90.0f, 0.0f)); break; } case QDataVis::PresetLeft: { - Q3DCamera::setRotationsPrivate(QPointF(90.0f, 22.5f)); + d_ptr->setRotations(QPointF(90.0f, 22.5f)); break; } case QDataVis::PresetLeftHigh: { - Q3DCamera::setRotationsPrivate(QPointF(90.0f, 45.0f)); + d_ptr->setRotations(QPointF(90.0f, 45.0f)); break; } case QDataVis::PresetRightLow: { - Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 0.0f)); + d_ptr->setRotations(QPointF(-90.0f, 0.0f)); break; } case QDataVis::PresetRight: { - Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 22.5f)); + d_ptr->setRotations(QPointF(-90.0f, 22.5f)); break; } case QDataVis::PresetRightHigh: { - Q3DCamera::setRotationsPrivate(QPointF(-90.0f, 45.0f)); + d_ptr->setRotations(QPointF(-90.0f, 45.0f)); break; } case QDataVis::PresetBehindLow: { - Q3DCamera::setRotationsPrivate(QPointF(180.0f, 0.0f)); + d_ptr->setRotations(QPointF(180.0f, 0.0f)); break; } case QDataVis::PresetBehind: { - Q3DCamera::setRotationsPrivate(QPointF(180.0f, 22.5f)); + d_ptr->setRotations(QPointF(180.0f, 22.5f)); break; } case QDataVis::PresetBehindHigh: { - Q3DCamera::setRotationsPrivate(QPointF(180.0f, 45.0f)); + d_ptr->setRotations(QPointF(180.0f, 45.0f)); break; } case QDataVis::PresetIsometricLeft: { - Q3DCamera::setRotationsPrivate(QPointF(45.0f, 22.5f)); + d_ptr->setRotations(QPointF(45.0f, 22.5f)); break; } case QDataVis::PresetIsometricLeftHigh: { - Q3DCamera::setRotationsPrivate(QPointF(45.0f, 45.0f)); + d_ptr->setRotations(QPointF(45.0f, 45.0f)); break; } case QDataVis::PresetIsometricRight: { - Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 22.5f)); + d_ptr->setRotations(QPointF(-45.0f, 22.5f)); break; } case QDataVis::PresetIsometricRightHigh: { - Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 45.0f)); + d_ptr->setRotations(QPointF(-45.0f, 45.0f)); break; } case QDataVis::PresetDirectlyAbove: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, 90.0f)); + d_ptr->setRotations(QPointF(0.0f, 90.0f)); break; } case QDataVis::PresetDirectlyAboveCW45: { - Q3DCamera::setRotationsPrivate(QPointF(-45.0f, 90.0f)); + d_ptr->setRotations(QPointF(-45.0f, 90.0f)); break; } case QDataVis::PresetDirectlyAboveCCW45: { - Q3DCamera::setRotationsPrivate(QPointF(45.0f, 90.0f)); + d_ptr->setRotations(QPointF(45.0f, 90.0f)); break; } case QDataVis::PresetFrontBelow: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, -45.0f)); + d_ptr->setRotations(QPointF(0.0f, -45.0f)); break; } case QDataVis::PresetLeftBelow: { - Q3DCamera::setRotationsPrivate(QPointF(90.0f, -45.0f)); + d_ptr->setRotations(QPointF(90.0f, -45.0f)); break; } case QDataVis::PresetRightBelow: { - Q3DCamera::setRotationsPrivate(QPointF(-90.0f, -45.0f)); + d_ptr->setRotations(QPointF(-90.0f, -45.0f)); break; } case QDataVis::PresetBehindBelow: { - Q3DCamera::setRotationsPrivate(QPointF(180.0f, -45.0f)); + d_ptr->setRotations(QPointF(180.0f, -45.0f)); break; } case QDataVis::PresetDirectlyBelow: { - Q3DCamera::setRotationsPrivate(QPointF(0.0f, -90.0f)); + d_ptr->setRotations(QPointF(0.0f, -90.0f)); break; } default: @@ -236,18 +247,18 @@ void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset) break; } - d_ptr->m_activePreset = preset; -} - -void Q3DCamera::setRotationsPrivate(const QPointF &rotation) -{ - d_ptr->m_xRotation = rotation.x(); - d_ptr->m_yRotation = rotation.y(); + if (d_ptr->m_activePreset != preset) { + d_ptr->m_activePreset = preset; + setDirty(true); + } } void Q3DCamera::setZoomLevel(int zoomLevel) { - d_ptr->m_zoomLevel = zoomLevel; + if (d_ptr->m_zoomLevel != zoomLevel) { + d_ptr->m_zoomLevel = zoomLevel; + setDirty(true); + } } int Q3DCamera::zoomLevel() @@ -256,8 +267,8 @@ int Q3DCamera::zoomLevel() } QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relativePosition, - GLfloat fixedRotation, - GLfloat distanceModifier) const + qreal fixedRotation, + qreal distanceModifier) const { // Move the position with camera GLfloat radiusFactor = relativePosition.z() * (1.5f + distanceModifier); @@ -283,7 +294,10 @@ QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relative Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) : q_ptr(q), - m_zoomLevel(100) + m_xRotation(0.0f), + m_yRotation(0.0f), + m_zoomLevel(100), + m_activePreset(QDataVis::NoPreset) { } @@ -292,4 +306,24 @@ Q3DCameraPrivate::~Q3DCameraPrivate() { } +// Copies changed values from this camera to the other camera. If the other camera had same changes, +// those changes are discarded. +void Q3DCameraPrivate::sync(Q3DCamera &other) +{ + if (q_ptr->isDirty()) { + other.copyValuesFrom(*q_ptr); + q_ptr->setDirty(false); + other.setDirty(false); + } +} + +void Q3DCameraPrivate::setRotations(const QPointF &rotation) +{ + if (m_xRotation != rotation.x() || m_yRotation != rotation.y()) { + m_xRotation = rotation.x(); + m_yRotation = rotation.y(); + q_ptr->setDirty(true); + } +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h index ed09c3e1..2db4b300 100644 --- a/src/datavisualization/engine/q3dcamera.h +++ b/src/datavisualization/engine/q3dcamera.h @@ -19,13 +19,9 @@ #ifndef Q3DCAMERA_H #define Q3DCAMERA_H -#include <QObject> +#include <QtDataVisualization/q3dobject.h> #include <QMatrix4x4> -#include "datavisualizationglobal_p.h" -#include "q3dbars.h" -#include "q3dobject.h" - class QVector3D; class QPoint; class QPointF; @@ -63,7 +59,7 @@ public: const QVector3D &defaultUp); // Calculate view matrix based on zoomadjustment, current rotation and current zoom level - virtual void updateViewMatrix(GLfloat zoomAdjustment); + virtual void updateViewMatrix(qreal zoomAdjustment); virtual void setCameraPreset(QDataVis::CameraPreset preset); virtual QDataVis::CameraPreset cameraPreset(); @@ -72,14 +68,16 @@ public: virtual int zoomLevel(); virtual QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition, - GLfloat fixedRotation, - GLfloat distanceModifier) const; + qreal fixedRotation, + qreal distanceModifier) const; private: - void setRotationsPrivate(const QPointF &rotation); QScopedPointer<Q3DCameraPrivate> d_ptr; Q_DISABLE_COPY(Q3DCamera) + + friend class Q3DCameraPrivate; + friend class Q3DScenePrivate; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h index 75805d09..14556116 100644 --- a/src/datavisualization/engine/q3dcamera_p.h +++ b/src/datavisualization/engine/q3dcamera_p.h @@ -30,8 +30,7 @@ #define Q3DCAMERA_P_H #include "datavisualizationglobal_p.h" -#include "q3dbars.h" -#include <QObject> +#include "q3dcamera.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -43,8 +42,13 @@ public: Q3DCameraPrivate(Q3DCamera *q); ~Q3DCameraPrivate(); + void sync(Q3DCamera &other); + + void setRotations(const QPointF &rotation); + public: Q3DCamera *q_ptr; + QVector3D m_target; QVector3D m_up; diff --git a/src/datavisualization/engine/q3dlight.cpp b/src/datavisualization/engine/q3dlight.cpp index 80debb83..214efa5d 100644 --- a/src/datavisualization/engine/q3dlight.cpp +++ b/src/datavisualization/engine/q3dlight.cpp @@ -46,4 +46,15 @@ Q3DLightPrivate::~Q3DLightPrivate() { } +// Copies changed values from this light to the other light. If the other light had same changes, +// those changes are discarded. +void Q3DLightPrivate::sync(Q3DLight &other) +{ + if (q_ptr->isDirty()) { + other.copyValuesFrom(*q_ptr); + q_ptr->setDirty(false); + other.setDirty(false); + } +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dlight.h b/src/datavisualization/engine/q3dlight.h index 1a7ef739..0a4ba174 100644 --- a/src/datavisualization/engine/q3dlight.h +++ b/src/datavisualization/engine/q3dlight.h @@ -19,10 +19,7 @@ #ifndef Q3DLIGHT_H #define Q3DLIGHT_H -#include <QObject> - -#include "datavisualizationglobal_p.h" -#include "q3dobject.h" +#include <QtDataVisualization/q3dobject.h> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -43,6 +40,9 @@ private: QScopedPointer<Q3DLightPrivate> d_ptr; Q_DISABLE_COPY(Q3DLight) + + friend class Q3DLightPrivate; + friend class Q3DScenePrivate; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dlight_p.h b/src/datavisualization/engine/q3dlight_p.h index d0d28052..dad6d670 100644 --- a/src/datavisualization/engine/q3dlight_p.h +++ b/src/datavisualization/engine/q3dlight_p.h @@ -30,6 +30,7 @@ #define Q3DLIGHT_P_H #include "datavisualizationglobal_p.h" +#include "q3dlight.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -42,9 +43,10 @@ public: Q3DLightPrivate(Q3DLight *q); ~Q3DLightPrivate(); + void sync(Q3DLight &other); + public: Q3DLight *q_ptr; - }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp index cd609ae6..ac110d82 100644 --- a/src/datavisualization/engine/q3dobject.cpp +++ b/src/datavisualization/engine/q3dobject.cpp @@ -36,11 +36,15 @@ void Q3DObject::copyValuesFrom(const Q3DObject &source) d_ptr->m_position.setX(source.d_ptr->m_position.x()); d_ptr->m_position.setY(source.d_ptr->m_position.y()); d_ptr->m_position.setZ(source.d_ptr->m_position.z()); + setDirty(true); } void Q3DObject::setParentScene(Q3DScene *parentScene) { - d_ptr->m_parentScene = parentScene; + if (d_ptr->m_parentScene != parentScene) { + d_ptr->m_parentScene = parentScene; + setDirty(true); + } } Q3DScene *Q3DObject::parentScene() @@ -50,7 +54,10 @@ Q3DScene *Q3DObject::parentScene() void Q3DObject::setPosition(const QVector3D &position) { - d_ptr->m_position = position; + if (d_ptr->m_position != position) { + d_ptr->m_position = position; + setDirty(true); + } } QVector3D Q3DObject::position() const @@ -58,10 +65,26 @@ QVector3D Q3DObject::position() const return d_ptr->m_position; } +/*! + * \internal + */ +void Q3DObject::setDirty(bool dirty) +{ + d_ptr->m_isDirty = dirty; +} + +/*! + * \internal + */ +bool Q3DObject::isDirty() const +{ + return d_ptr->m_isDirty; +} Q3DObjectPrivate::Q3DObjectPrivate(Q3DObject *q) : q_ptr(q), - m_parentScene(0) + m_parentScene(0), + m_isDirty(true) { } diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h index 85bb3858..0b234891 100644 --- a/src/datavisualization/engine/q3dobject.h +++ b/src/datavisualization/engine/q3dobject.h @@ -19,8 +19,9 @@ #ifndef Q3DOBJECT_H #define Q3DOBJECT_H +#include <QtDataVisualization/qdatavisualizationenums.h> #include <QObject> -#include "datavisualizationglobal_p.h" +#include <QVector3D> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -43,10 +44,16 @@ public: virtual void setPosition(const QVector3D &position); virtual QVector3D position() const; +protected: + void setDirty(bool dirty); + bool isDirty() const; + private: QScopedPointer<Q3DObjectPrivate> d_ptr; Q_DISABLE_COPY(Q3DObject) + + friend class Q3DScenePrivate; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dobject_p.h b/src/datavisualization/engine/q3dobject_p.h index d1064731..7348c2e8 100644 --- a/src/datavisualization/engine/q3dobject_p.h +++ b/src/datavisualization/engine/q3dobject_p.h @@ -46,6 +46,7 @@ public: Q3DObject *q_ptr; Q3DScene *m_parentScene; QVector3D m_position; + bool m_isDirty; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp index b39daab6..29eb54f4 100644 --- a/src/datavisualization/engine/q3dscene.cpp +++ b/src/datavisualization/engine/q3dscene.cpp @@ -22,8 +22,8 @@ #include "q3dscene.h" #include "q3dscene_p.h" -#include "q3dcamera.h" -#include "q3dlight.h" +#include "q3dcamera_p.h" +#include "q3dlight_p.h" QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -31,31 +31,8 @@ Q3DScene::Q3DScene(QObject *parent) : QObject(parent), d_ptr(new Q3DScenePrivate(this)) { -} - -Q3DScene *Q3DScene::clone(QObject *parent) -{ - Q3DScene *cloneScene = new Q3DScene(parent); - cloneScene->setViewport(viewport()); - cloneScene->setMainViewport(mainViewport()); - cloneScene->setSliceViewport(sliceViewport()); - - if (d_ptr->m_camera) { - Q3DCamera *cloneCamera = new Q3DCamera(); - cloneCamera->copyValuesFrom(*d_ptr->m_camera); - cloneScene->setCamera(cloneCamera); - } - - if (d_ptr->m_light) { - Q3DLight *cloneLight = new Q3DLight(); - cloneLight->copyValuesFrom(*d_ptr->m_light); - cloneScene->setLight(cloneLight); - } - - cloneScene->setSlicingActivated(isSlicingActivated()); - cloneScene->setUnderSideCameraEnabled(isUnderSideCameraEnabled()); - - return cloneScene; + setCamera(new Q3DCamera(0)); + setLight(new Q3DLight(0)); } Q3DScene::~Q3DScene() @@ -69,15 +46,22 @@ QRect Q3DScene::viewport() const void Q3DScene::setViewport(const QRect &viewport) { - d_ptr->m_viewport = viewport; - d_ptr->m_viewport.setX(0); - d_ptr->m_viewport.setY(0); + if (d_ptr->m_viewport.width() != viewport.width() + || d_ptr->m_viewport.height() != viewport.height()) { + d_ptr->m_viewport = viewport; + d_ptr->m_viewport.setX(0); + d_ptr->m_viewport.setY(0); + d_ptr->m_changeTracker.viewportChanged = true; + } } void Q3DScene::setViewportSize(int width, int height) { - d_ptr->m_viewport.setWidth(width); - d_ptr->m_viewport.setHeight(height); + if (d_ptr->m_viewport.width() != width || d_ptr->m_viewport.height() != height) { + d_ptr->m_viewport.setWidth(width); + d_ptr->m_viewport.setHeight(height); + d_ptr->m_changeTracker.viewportChanged = true; + } } QRect Q3DScene::mainViewport() const @@ -87,7 +71,10 @@ QRect Q3DScene::mainViewport() const void Q3DScene::setMainViewport(const QRect &mainViewPort) { - d_ptr->m_mainViewport = mainViewPort; + if (d_ptr->m_mainViewport != mainViewPort) { + d_ptr->m_mainViewport = mainViewPort; + d_ptr->m_changeTracker.mainViewportChanged = true; + } } bool Q3DScene::isInputInsideMainView(const QPoint &point) @@ -121,7 +108,10 @@ QRect Q3DScene::sliceViewport() const void Q3DScene::setSliceViewport(const QRect &sliceViewPort) { - d_ptr->m_sliceViewport = sliceViewPort; + if (d_ptr->m_sliceViewport != sliceViewPort) { + d_ptr->m_sliceViewport = sliceViewPort; + d_ptr->m_changeTracker.sliceViewportChanged = true; + } } // TODO: Refactor the current way of building the scene... @@ -134,11 +124,16 @@ Q3DCamera *Q3DScene::camera() const void Q3DScene::setCamera(Q3DCamera *camera) { - if (d_ptr->m_camera) - d_ptr->m_camera->setParentScene(0); + if (camera != d_ptr->m_camera) { + // TODO Do we need to be able to swap cameras? May need similar ownership mechanism like axes + delete d_ptr->m_camera; + + d_ptr->m_camera = camera; + d_ptr->m_camera->setParentScene(this); - d_ptr->m_camera = camera; - d_ptr->m_camera->setParentScene(this); + d_ptr->m_changeTracker.cameraChanged = true; + + } } Q3DLight *Q3DScene::light() const @@ -148,11 +143,15 @@ Q3DLight *Q3DScene::light() const void Q3DScene::setLight(Q3DLight *light) { - if (d_ptr->m_light) - d_ptr->m_light->setParentScene(0); + if (light != d_ptr->m_light) { + // TODO Do we need to be able to swap lights? May need similar ownership mechanism like axes + delete d_ptr->m_light; - d_ptr->m_light = light; - d_ptr->m_light->setParentScene(this); + d_ptr->m_light = light; + d_ptr->m_light->setParentScene(this); + + d_ptr->m_changeTracker.lightChanged = true; + } } bool Q3DScene::isUnderSideCameraEnabled() const @@ -162,7 +161,10 @@ bool Q3DScene::isUnderSideCameraEnabled() const void Q3DScene::setUnderSideCameraEnabled(bool isEnabled) { - d_ptr->m_isUnderSideCameraEnabled = isEnabled; + if (d_ptr->m_isUnderSideCameraEnabled != isEnabled) { + d_ptr->m_isUnderSideCameraEnabled = isEnabled; + d_ptr->m_changeTracker.underSideCameraEnabledChanged = true; + } } bool Q3DScene::isSlicingActivated() const @@ -172,20 +174,26 @@ bool Q3DScene::isSlicingActivated() const void Q3DScene::setSlicingActivated(bool isSlicing) { - if (isSlicing != d_ptr->m_isSlicingActivated) + if (d_ptr->m_isSlicingActivated != isSlicing) { d_ptr->m_isSlicingActivated = isSlicing; + d_ptr->m_changeTracker.slicingActivatedChanged = true; + } } -void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition, GLfloat fixedRotation, GLfloat distanceModifier) +void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition, + qreal fixedRotation, qreal distanceModifier) { - d_ptr->m_light->setPosition(d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition, fixedRotation, distanceModifier)); + d_ptr->m_light->setPosition( + d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition, + fixedRotation, + distanceModifier)); } Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) : q_ptr(q), - m_camera(0), - m_light(0), + m_camera(), + m_light(), m_isUnderSideCameraEnabled(false), m_isSlicingActivated(false) { @@ -197,4 +205,49 @@ Q3DScenePrivate::~Q3DScenePrivate() delete m_light; } +// Copies changed values from this scene to the other scene. If the other scene had same changes, +// those changes are discarded. +void Q3DScenePrivate::sync(Q3DScenePrivate &other) +{ + if (m_changeTracker.viewportChanged) { + other.q_ptr->setViewport(q_ptr->viewport()); + m_changeTracker.viewportChanged = false; + other.m_changeTracker.viewportChanged = false; + } + if (m_changeTracker.mainViewportChanged) { + other.q_ptr->setMainViewport(q_ptr->mainViewport()); + m_changeTracker.mainViewportChanged = false; + other.m_changeTracker.mainViewportChanged = false; + } + if (m_changeTracker.sliceViewportChanged) { + other.q_ptr->setSliceViewport(q_ptr->sliceViewport()); + m_changeTracker.sliceViewportChanged = false; + other.m_changeTracker.sliceViewportChanged = false; + } + if (m_changeTracker.cameraChanged) { + m_camera->setDirty(true); + m_changeTracker.cameraChanged = false; + other.m_changeTracker.cameraChanged = false; + } + m_camera->d_ptr->sync(*other.m_camera); + + if (m_changeTracker.lightChanged) { + m_light->setDirty(true); + m_changeTracker.lightChanged = false; + other.m_changeTracker.lightChanged = false; + } + m_light->d_ptr->sync(*other.m_light); + + if (m_changeTracker.underSideCameraEnabledChanged) { + other.q_ptr->setUnderSideCameraEnabled(q_ptr->isUnderSideCameraEnabled()); + m_changeTracker.underSideCameraEnabledChanged = false; + other.m_changeTracker.underSideCameraEnabledChanged = false; + } + if (m_changeTracker.slicingActivatedChanged) { + other.q_ptr->setSlicingActivated(q_ptr->isSlicingActivated()); + m_changeTracker.slicingActivatedChanged = false; + other.m_changeTracker.slicingActivatedChanged = false; + } +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h index 352a3b82..7a2a6e30 100644 --- a/src/datavisualization/engine/q3dscene.h +++ b/src/datavisualization/engine/q3dscene.h @@ -19,18 +19,15 @@ #ifndef Q3DSCENE_H #define Q3DSCENE_H +#include <QtDataVisualization/qdatavisualizationenums.h> #include <QObject> -#include "datavisualizationglobal_p.h" -#include "q3dscene_p.h" - QT_DATAVISUALIZATION_BEGIN_NAMESPACE class Q3DCamera; class Q3DBox; class Q3DLight; - -// Note: Scene doesn't take ownership of any of the objects given as parameter. Upon destruction of the scene it will call setParentScene(0) on it's child objects. +class Q3DScenePrivate; class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject { @@ -40,8 +37,6 @@ public: Q3DScene(QObject *parent = 0); ~Q3DScene(); - Q3DScene *clone(QObject *parent = 0); - QRect viewport() const; void setViewport(const QRect &viewport); void setViewportSize(int width, int height); @@ -69,13 +64,15 @@ public: // Calcluate light position based on rotation. // Call after calling calculateViewMatrix to get up-to-date position void setLightPositionRelativeToCamera(const QVector3D &relativePosition, - GLfloat fixedRotation = 0.0f, - GLfloat distanceModifier = 0.0f); + qreal fixedRotation = 0.0, + qreal distanceModifier = 0.0); private: QScopedPointer<Q3DScenePrivate> d_ptr; Q_DISABLE_COPY(Q3DScene) + + friend class Abstract3DRenderer; }; QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h index 86386a75..29c7bdc4 100644 --- a/src/datavisualization/engine/q3dscene_p.h +++ b/src/datavisualization/engine/q3dscene_p.h @@ -29,9 +29,8 @@ #ifndef Q3DSCENE_P_H #define Q3DSCENE_P_H -#include <QRect> - #include "datavisualizationglobal_p.h" +#include <QRect> QT_DATAVISUALIZATION_BEGIN_NAMESPACE @@ -39,13 +38,38 @@ class Q3DCamera; class Q3DLight; class Q3DScene; +struct Q3DSceneChangeBitField { + bool viewportChanged : 1; + bool mainViewportChanged : 1; + bool sliceViewportChanged : 1; + bool cameraChanged : 1; + bool lightChanged : 1; + bool underSideCameraEnabledChanged : 1; + bool slicingActivatedChanged : 1; + + Q3DSceneChangeBitField() + : viewportChanged(true), + mainViewportChanged(true), + sliceViewportChanged(true), + cameraChanged(true), + lightChanged(true), + underSideCameraEnabledChanged(true), + slicingActivatedChanged(true) + { + } +}; + class Q3DScenePrivate { public: Q3DScenePrivate(Q3DScene *q); ~Q3DScenePrivate(); + void sync(Q3DScenePrivate &other); + Q3DScene *q_ptr; + Q3DSceneChangeBitField m_changeTracker; + QRect m_viewport; QRect m_mainViewport; QRect m_sliceViewport; diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp index dc50aef0..a19f3e82 100644 --- a/src/datavisualization/engine/selectionpointer.cpp +++ b/src/datavisualization/engine/selectionpointer.cpp @@ -84,9 +84,9 @@ void SelectionPointer::initializeOpenGL() void SelectionPointer::updateScene(Q3DScene *scene) { - // Make a copy of the scene. - delete m_cachedScene; - m_cachedScene = scene->clone(); + Q_UNUSED(scene) + // Synchronize the scenes + // TODO } void SelectionPointer::render(GLuint defaultFboHandle) |