From 61c84e2d9c46de40d22f6fafbdd23d4015025516 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 7 Feb 2014 15:30:53 +0200 Subject: Mostly revert the rotations refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quaternions are actually easier to use in most use cases. Added some convenience functionality for QML to enable using axis/angle combinations, too. Change-Id: I61c76e0967b4808aa9adaf43dfe6f4596c9ce353 Reviewed-by: Tomi Korpipää --- src/datavisualization/data/qabstract3dseries.cpp | 100 +++++++-------------- src/datavisualization/data/qabstract3dseries.h | 15 ++-- src/datavisualization/data/qabstract3dseries_p.h | 6 +- src/datavisualization/data/qbar3dseries.cpp | 57 ++++++++++++ src/datavisualization/data/qbar3dseries.h | 5 ++ src/datavisualization/data/qbar3dseries_p.h | 4 + .../data/qitemmodelscatterdataproxy.cpp | 68 +++++--------- .../data/qitemmodelscatterdataproxy.h | 17 ++-- .../data/qitemmodelscatterdataproxy_p.h | 3 +- src/datavisualization/data/qscatterdataitem.cpp | 51 +++-------- src/datavisualization/data/qscatterdataitem.h | 13 ++- .../data/scatteritemmodelhandler.cpp | 52 ++++++----- .../data/scatteritemmodelhandler_p.h | 3 +- src/datavisualization/engine/bars3drenderer.cpp | 5 -- src/datavisualization/engine/bars3drenderer_p.h | 1 - src/datavisualization/engine/scatter3drenderer.cpp | 10 +-- src/datavisualization/engine/seriesrendercache.cpp | 8 +- 17 files changed, 196 insertions(+), 222 deletions(-) (limited to 'src') diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp index fbc72410..4d201c45 100644 --- a/src/datavisualization/data/qabstract3dseries.cpp +++ b/src/datavisualization/data/qabstract3dseries.cpp @@ -142,28 +142,15 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! - * \qmlproperty vector3d Abstract3DSeries::meshRotationAxis + * \qmlproperty quaternion Abstract3DSeries::meshRotation * - * Sets the mesh rotation \a axis that is applied to all items of the series. - * For those series types that support item specific rotation, the resulting - * rotation quaternions are multiplied together at render time. - * Bar3DSeries ignores rotation axis, as it only supports rotation around Y-axis. + * Sets the mesh \a rotation that is applied to all items of the series. + * The \a rotation should be a normalized quaternion. + * For those series types that support item specific rotation, the rotations are + * multiplied together. + * Bar3DSeries ignores any rotation that is not around Y-axis. * Surface3DSeries applies the rotation only to the selection pointer. - * Defaults to Y-axis. - * - * \sa meshRotationAngle - */ - -/*! - * \qmlproperty float Abstract3DSeries::meshRotationAngle - * - * Sets the mesh rotation \a angle that is applied to all items of the series. - * For those series types that support item specific rotation, the resulting - * rotation quaternions are multiplied together at render time. - * Surface3DSeries applies the rotation only to the selection pointer. - * Defaults to 0. - * - * \sa meshRotationAxis + * Defaults to no rotation. */ /*! @@ -252,6 +239,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * \sa itemLabelFormat */ +/*! + * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle) + * + * A convenience function to construct mesh rotation quaternion from axis and angle. + * + * \sa meshRotation + */ + /*! * \internal */ @@ -364,54 +359,37 @@ bool QAbstract3DSeries::isMeshSmooth() const } /*! - * \property QAbstract3DSeries::meshRotationAxis + * \property QAbstract3DSeries::meshRotation * - * Sets the mesh rotation \a axis that is applied to all items of the series. - * For those series types that support item specific rotation, the resulting - * rotation quaternions are multiplied together at render time. - * QBar3DSeries ignores rotation axis, as it only supports rotation around Y-axis. + * Sets the mesh \a rotation that is applied to all items of the series. + * The \a rotation should be a normalized QQuaternion. + * For those series types that support item specific rotation, the rotations are + * multiplied together. + * QBar3DSeries ignores any rotation that is not around Y-axis. * QSurface3DSeries applies the rotation only to the selection pointer. - * Defaults to Y-axis. - * - * \sa meshRotationAngle + * Defaults to no rotation. */ -void QAbstract3DSeries::setMeshRotationAxis(const QVector3D &axis) +void QAbstract3DSeries::setMeshRotation(const QQuaternion &rotation) { - if (d_ptr->m_type != SeriesTypeBar) { - if (d_ptr->m_meshRotationAxis != axis) { - d_ptr->setMeshRotationAxis(axis); - emit meshRotationAxisChanged(axis); - } + if (d_ptr->m_meshRotation != rotation) { + d_ptr->setMeshRotation(rotation); + emit meshRotationChanged(rotation); } } -QVector3D QAbstract3DSeries::meshRotationAxis() const +QQuaternion QAbstract3DSeries::meshRotation() const { - return d_ptr->m_meshRotationAxis; + return d_ptr->m_meshRotation; } /*! - * \property QAbstract3DSeries::meshRotationAngle + * A convenience function to construct mesh rotation quaternion from \a axis and \a angle. * - * Sets the mesh rotation \a angle that is applied to all items of the series. - * For those series types that support item specific rotation, the resulting - * rotation quaternions are multiplied together at render time. - * QSurface3DSeries applies the rotation only to the selection pointer. - * Defaults to 0. - * - * \sa meshRotationAxis + * \sa meshRotation */ -void QAbstract3DSeries::setMeshRotationAngle(float angle) -{ - if (d_ptr->m_meshRotationAngle != angle) { - d_ptr->setMeshRotationAngle(angle); - emit meshRotationAngleChanged(angle); - } -} - -float QAbstract3DSeries::meshRotationAngle() const +void QAbstract3DSeries::setMeshAxisAndAngle(const QVector3D &axis, float angle) { - return d_ptr->m_meshRotationAngle; + setMeshRotation(QQuaternion::fromAxisAndAngle(axis, angle)); } /*! @@ -619,8 +597,6 @@ QAbstract3DSeriesPrivate::QAbstract3DSeriesPrivate(QAbstract3DSeries *q, QAbstra m_controller(0), m_mesh(QAbstract3DSeries::MeshCube), m_meshSmooth(false), - m_meshRotationAxis(upVector), - m_meshRotationAngle(0.0f), m_colorStyle(Q3DTheme::ColorStyleUniform) { } @@ -687,17 +663,9 @@ void QAbstract3DSeriesPrivate::setMeshSmooth(bool enable) m_controller->markSeriesVisualsDirty(); } -void QAbstract3DSeriesPrivate::setMeshRotationAxis(const QVector3D &axis) -{ - m_meshRotationAxis = axis; - m_changeTracker.meshRotationChanged = true; - if (m_controller) - m_controller->markSeriesVisualsDirty(); -} - -void QAbstract3DSeriesPrivate::setMeshRotationAngle(float angle) +void QAbstract3DSeriesPrivate::setMeshRotation(const QQuaternion &rotation) { - m_meshRotationAngle = angle; + m_meshRotation = rotation; m_changeTracker.meshRotationChanged = true; if (m_controller) m_controller->markSeriesVisualsDirty(); diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h index b0396126..a8cee7c9 100644 --- a/src/datavisualization/data/qabstract3dseries.h +++ b/src/datavisualization/data/qabstract3dseries.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -39,8 +39,7 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DSeries : public QObject Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged) Q_PROPERTY(Mesh mesh READ mesh WRITE setMesh NOTIFY meshChanged) Q_PROPERTY(bool meshSmooth READ isMeshSmooth WRITE setMeshSmooth NOTIFY meshSmoothChanged) - Q_PROPERTY(QVector3D meshRotationAxis READ meshRotationAxis WRITE setMeshRotationAxis NOTIFY meshRotationAxisChanged) - Q_PROPERTY(float meshRotationAngle READ meshRotationAngle WRITE setMeshRotationAngle NOTIFY meshRotationAngleChanged) + Q_PROPERTY(QQuaternion meshRotation READ meshRotation WRITE setMeshRotation NOTIFY meshRotationChanged) Q_PROPERTY(QString userDefinedMesh READ userDefinedMesh WRITE setUserDefinedMesh NOTIFY userDefinedMeshChanged) Q_PROPERTY(QtDataVisualization::Q3DTheme::ColorStyle colorStyle READ colorStyle WRITE setColorStyle NOTIFY colorStyleChanged) Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor NOTIFY baseColorChanged) @@ -94,10 +93,9 @@ public: void setMeshSmooth(bool enable); bool isMeshSmooth() const; - void setMeshRotationAxis(const QVector3D &axis); - QVector3D meshRotationAxis() const; - void setMeshRotationAngle(float angle); - float meshRotationAngle() const; + void setMeshRotation(const QQuaternion &rotation); + QQuaternion meshRotation() const; + Q_INVOKABLE void setMeshAxisAndAngle(const QVector3D &axis, float angle); void setUserDefinedMesh(const QString &fileName); QString userDefinedMesh() const; @@ -125,8 +123,7 @@ signals: void visibilityChanged(bool visible); void meshChanged(Mesh mesh); void meshSmoothChanged(bool enabled); - void meshRotationAxisChanged(QVector3D axis); - void meshRotationAngleChanged(float angle); + void meshRotationChanged(QQuaternion rotation); void userDefinedMeshChanged(QString fileName); void colorStyleChanged(Q3DTheme::ColorStyle style); void baseColorChanged(QColor color); diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h index 3c9a9582..6fbabd3d 100644 --- a/src/datavisualization/data/qabstract3dseries_p.h +++ b/src/datavisualization/data/qabstract3dseries_p.h @@ -108,8 +108,7 @@ public: void setVisible(bool visible); void setMesh(QAbstract3DSeries::Mesh mesh); void setMeshSmooth(bool enable); - void setMeshRotationAxis(const QVector3D &axis); - void setMeshRotationAngle(float angle); + void setMeshRotation(const QQuaternion &rotation); void setUserDefinedMesh(const QString &meshFile); void setColorStyle(Q3DTheme::ColorStyle style); @@ -133,8 +132,7 @@ public: Abstract3DController *m_controller; QAbstract3DSeries::Mesh m_mesh; bool m_meshSmooth; - QVector3D m_meshRotationAxis; - float m_meshRotationAngle; + QQuaternion m_meshRotation; QString m_userDefinedMesh; Q3DTheme::ColorStyle m_colorStyle; diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp index 124f996b..6e681b7e 100644 --- a/src/datavisualization/data/qbar3dseries.cpp +++ b/src/datavisualization/data/qbar3dseries.cpp @@ -114,6 +114,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * \sa AbstractGraph3D::clearSelection() */ +/*! + * \qmlproperty real Bar3DSeries::meshAngle + * + * A convenience property for defining the series rotation \a angle in degrees. + * + * \note: When reading this property, it is calculated from Abstract3DSeries::meshRotation value + * with floating point precision and always returns a value from zero to 360 degrees. + * + * \sa Abstract3DSeries::meshRotation + */ + /*! * Constructs QBar3DSeries with the given \a parent. */ @@ -122,6 +133,7 @@ QBar3DSeries::QBar3DSeries(QObject *parent) : { // Default proxy dptr()->setDataProxy(new QBarDataProxy); + dptr()->connectSignals(); } /*! @@ -131,6 +143,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent) { dptr()->setDataProxy(dataProxy); + dptr()->connectSignals(); } /*! @@ -139,6 +152,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) : QAbstract3DSeries(d, parent) { + dptr()->connectSignals(); } /*! @@ -205,6 +219,38 @@ QPoint QBar3DSeries::invalidSelectionPosition() return Bars3DController::invalidSelectionPosition(); } +static inline float quaternionAngle(const QQuaternion &rotation) +{ + return qAcos(rotation.scalar()) * 360.0f / M_PI; +} + +/*! + * \property QBar3DSeries::meshAngle + * + * A convenience property for defining the series rotation \a angle in degrees. + * Setting this property is equivalent to the following call: + * \code setMeshRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, angle)) \endcode + * + * \note: When reading this property, it is calculated from QAbstract3DSeries::meshRotation value + * using floating point precision and always returns a value from zero to 360 degrees. + * + * \sa QAbstract3DSeries::meshRotation + */ +void QBar3DSeries::setMeshAngle(float angle) +{ + setMeshRotation(QQuaternion::fromAxisAndAngle(upVector, angle)); +} + +float QBar3DSeries::meshAngle() const +{ + QQuaternion rotation = meshRotation(); + + if (rotation.isIdentity() || rotation.x() != 0.0f || rotation.z() != 0.0f) + return 0.0f; + else + return quaternionAngle(rotation); +} + /*! * \internal */ @@ -280,6 +326,11 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon } } +void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation) +{ + emit qptr()->meshAngleChanged(quaternionAngle(rotation)); +} + void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position) { if (position != m_selectedBar) { @@ -288,4 +339,10 @@ void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position) } } +void QBar3DSeriesPrivate::connectSignals() +{ + QObject::connect(q_ptr, &QAbstract3DSeries::meshRotationChanged, this, + &QBar3DSeriesPrivate::handleMeshRotationChanged); +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h index be748516..aa67dadb 100644 --- a/src/datavisualization/data/qbar3dseries.h +++ b/src/datavisualization/data/qbar3dseries.h @@ -32,6 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QBar3DSeries : public QAbstract3DSeries Q_OBJECT Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged) Q_PROPERTY(QPoint selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged) + Q_PROPERTY(float meshAngle READ meshAngle WRITE setMeshAngle NOTIFY meshAngleChanged) public: explicit QBar3DSeries(QObject *parent = 0); @@ -45,9 +46,13 @@ public: QPoint selectedBar() const; static QPoint invalidSelectionPosition(); + void setMeshAngle(float angle); + float meshAngle() const; + signals: void dataProxyChanged(QBarDataProxy *proxy); void selectedBarChanged(QPoint position); + void meshAngleChanged(float angle); protected: explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0); diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h index 173f1cd9..718f1237 100644 --- a/src/datavisualization/data/qbar3dseries_p.h +++ b/src/datavisualization/data/qbar3dseries_p.h @@ -44,8 +44,12 @@ public: virtual void setDataProxy(QAbstractDataProxy *proxy); virtual void connectControllerAndProxy(Abstract3DController *newController); + void handleMeshRotationChanged(const QQuaternion &rotation); + void setSelectedBar(const QPoint &position); + void connectSignals(); + private: QBar3DSeries *qptr(); diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp index b73538e9..4f407075 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp @@ -93,15 +93,13 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! - * \qmlproperty string ItemModelScatterDataProxy::rotationAxisRole + * \qmlproperty string ItemModelScatterDataProxy::rotationRole * - * Defines the rotation axis role for the mapping. - */ - -/*! - * \qmlproperty string ItemModelScatterDataProxy::rotationAngleRole - * - * Defines the rotation angle role for the mapping. + * Defines the rotation role for the mapping. + * The model may supply the value for rotation as either variant that is directly convertible + * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first + * will construct the quaternion directly with given values, and the second one will construct + * the quaternion using QQuaternion::fromAxisAndAngle() method. */ /*! @@ -149,15 +147,13 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel * Constructs QItemModelScatterDataProxy with \a itemModel and optional \a parent. Proxy doesn't take * ownership of the \a itemModel, as typically item models are owned by other controls. * The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, zPosRole property - * to \a zPosRole, rotationAxisRole property to \a rotationAxisRole, and rotationAngleRole - * property to \a rotationAngleRole. + * to \a zPosRole, and rotationRole property to \a rotationRole. */ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, - const QString &rotationAxisRole, - const QString &rotationAngleRole, + const QString &rotationRole, QObject *parent) : QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent) { @@ -165,8 +161,7 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel dptr()->m_xPosRole = xPosRole; dptr()->m_yPosRole = yPosRole; dptr()->m_zPosRole = zPosRole; - dptr()->m_rotationAxisRole = rotationAxisRole; - dptr()->m_rotationAngleRole = rotationAngleRole; + dptr()->m_rotationRole = rotationRole; dptr()->connectItemModelHandler(); } @@ -248,53 +243,38 @@ QString QItemModelScatterDataProxy::zPosRole() const } /*! - * \property QItemModelScatterDataProxy::rotationAxisRole + * \property QItemModelScatterDataProxy::rotationRole * - * Defines the rotation axis role for the mapping. - */ -void QItemModelScatterDataProxy::setRotationAxisRole(const QString &role) -{ - if (dptr()->m_rotationAxisRole != role) { - dptr()->m_rotationAxisRole = role; - emit rotationAxisRoleChanged(role); - } -} - -QString QItemModelScatterDataProxy::rotationAxisRole() const -{ - return dptrc()->m_rotationAxisRole; -} - -/*! - * \property QItemModelScatterDataProxy::rotationAngleRole + * Defines the rotation role for the mapping. * - * Defines the rotation angle role for the mapping. + * The model may supply the value for rotation as either variant that is directly convertible + * to QQuartenion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first + * will construct the quaternion directly with given values, and the second one will construct + * the quaternion using QQuaternion::fromAxisAndAngle() method. */ -void QItemModelScatterDataProxy::setRotationAngleRole(const QString &role) +void QItemModelScatterDataProxy::setRotationRole(const QString &role) { - if (dptr()->m_rotationAngleRole != role) { - dptr()->m_rotationAngleRole = role; - emit rotationAngleRoleChanged(role); + if (dptr()->m_rotationRole != role) { + dptr()->m_rotationRole = role; + emit rotationRoleChanged(role); } } -QString QItemModelScatterDataProxy::rotationAngleRole() const +QString QItemModelScatterDataProxy::rotationRole() const { - return dptrc()->m_rotationAngleRole; + return dptrc()->m_rotationRole; } /*! - * Changes \a xPosRole, \a yPosRole, \a zPosRole, \a rotationAxis, and \a rotationAngle mapping. + * Changes \a xPosRole, \a yPosRole, \a zPosRole, and \a rotationRole mapping. */ void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole, - const QString &zPosRole, const QString &rotationAxis, - const QString &rotationAngle) + const QString &zPosRole, const QString &rotationRole) { setXPosRole(xPosRole); setYPosRole(yPosRole); setZPosRole(zPosRole); - setRotationAxisRole(rotationAxis); - setRotationAngleRole(rotationAngle); + setRotationRole(rotationRole); } /*! diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h index ec2deee2..ef950843 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h @@ -34,8 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDa Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged) Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged) Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged) - Q_PROPERTY(QString rotationAxisRole READ rotationAxisRole WRITE setRotationAxisRole NOTIFY rotationAxisRoleChanged) - Q_PROPERTY(QString rotationAngleRole READ rotationAngleRole WRITE setRotationAngleRole NOTIFY rotationAngleRoleChanged) + Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged) public: explicit QItemModelScatterDataProxy(QObject *parent = 0); @@ -45,8 +44,7 @@ public: const QString &zPosRole, QObject *parent = 0); QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, const QString &xPosRole, const QString &yPosRole, - const QString &zPosRole, const QString &rotationAxisRole, - const QString &rotationAngleRole, + const QString &zPosRole, const QString &rotationRole, QObject *parent = 0); virtual ~QItemModelScatterDataProxy(); @@ -59,21 +57,18 @@ public: QString yPosRole() const; void setZPosRole(const QString &role); QString zPosRole() const; - void setRotationAxisRole(const QString &role); - QString rotationAxisRole() const; - void setRotationAngleRole(const QString &role); - QString rotationAngleRole() const; + void setRotationRole(const QString &role); + QString rotationRole() const; void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, - const QString &rotationAxis, const QString &rotationAngle); + const QString &rotationRole); signals: void itemModelChanged(const QAbstractItemModel* itemModel); void xPosRoleChanged(QString role); void yPosRoleChanged(QString role); void zPosRoleChanged(QString role); - void rotationAxisRoleChanged(QString role); - void rotationAngleRoleChanged(QString role); + void rotationRoleChanged(QString role); protected: QItemModelScatterDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h index 7057c910..4e1f321f 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h @@ -52,8 +52,7 @@ private: QString m_xPosRole; QString m_yPosRole; QString m_zPosRole; - QString m_rotationAxisRole; - QString m_rotationAngleRole; + QString m_rotationRole; friend class ScatterItemModelHandler; friend class QItemModelScatterDataProxy; diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp index a3e7b12d..9751dfeb 100644 --- a/src/datavisualization/data/qscatterdataitem.cpp +++ b/src/datavisualization/data/qscatterdataitem.cpp @@ -37,9 +37,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * Constructs QScatterDataItem. */ QScatterDataItem::QScatterDataItem() - : d_ptr(0), // private data doesn't exist by default (optimization) - m_rotationAxis(upVector), - m_rotationAngle(0.0f) + : d_ptr(0) // private data doesn't exist by default (optimization) { } @@ -49,21 +47,17 @@ QScatterDataItem::QScatterDataItem() */ QScatterDataItem::QScatterDataItem(const QVector3D &position) : d_ptr(0), - m_position(position), - m_rotationAxis(upVector), - m_rotationAngle(0.0f) + m_position(position) { } /*! - * Constructs QScatterDataItem with \a position, \a rotationAxis and \a rotationAngle. + * Constructs QScatterDataItem with \a position and \a rotation. */ -QScatterDataItem::QScatterDataItem(const QVector3D &position, const QVector3D &rotationAxis, - float rotationAngle) +QScatterDataItem::QScatterDataItem(const QVector3D &position, const QQuaternion &rotation) : d_ptr(0), m_position(position), - m_rotationAxis(rotationAxis), - m_rotationAngle(rotationAngle) + m_rotation(rotation) { } @@ -88,8 +82,7 @@ QScatterDataItem::~QScatterDataItem() QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) { m_position = other.m_position; - m_rotationAxis = other.m_rotationAxis; - m_rotationAngle = other.m_rotationAngle; + m_rotation = other.m_rotation; if (other.d_ptr) createExtraData(); @@ -110,35 +103,17 @@ QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) */ /*! - * \fn void QScatterDataItem::setRotationAxis(const QVector3D &axis) - * Sets rotation \a axis of this data item. - * If the series also has rotation, the resulting rotation quaternions - * are multiplied together at render time. - * Defaults to Y-axis. - * - * \sa setRotationAngle() - */ - -/*! - * \fn QVector3D QScatterDataItem::rotationAxis() const - * \return rotation axis of this data item. - * \sa setRotationAxis(), setRotationAngle() - */ - -/*! - * \fn void QScatterDataItem::setRotationAngle(float angle) - * Sets rotation \a angle of this data item. - * If the series also has rotation, the resulting rotation quaternions - * are multiplied together at render time. + * \fn void QScatterDataItem::setRotation(const QQuaternion &rotation) + * Sets \a rotation to this data item. + * The \a rotation should be a normalized QQuaternion. + * If the series also has rotation, item and series rotations are multiplied together. * Defaults to no rotation. - * - * \sa setRotationAxis() */ /*! - * \fn float QScatterDataItem::rotationAngle() const - * \return rotation angle of this data item. - * \sa setRotationAxis(), setRotationAngle() + * \fn QQuaternion QScatterDataItem::rotation() const + * \return rotation of this data item. + * \sa setRotation() */ /*! diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h index 64337631..62ebac56 100644 --- a/src/datavisualization/data/qscatterdataitem.h +++ b/src/datavisualization/data/qscatterdataitem.h @@ -21,7 +21,7 @@ #include -#include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -32,7 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatterDataItem public: QScatterDataItem(); QScatterDataItem(const QVector3D &position); - QScatterDataItem(const QVector3D &position, const QVector3D &rotationAxis, float rotationAngle); + QScatterDataItem(const QVector3D &position, const QQuaternion &rotation); QScatterDataItem(const QScatterDataItem &other); ~QScatterDataItem(); @@ -40,10 +40,8 @@ public: inline void setPosition(const QVector3D &position) { m_position = position; } inline QVector3D position() const { return m_position; } - inline void setRotationAxis(const QVector3D &axis) { m_rotationAxis = axis; } - inline QVector3D rotationAxis() const { return m_rotationAxis; } - inline void setRotationAngle(float angle) { m_rotationAngle = angle; } - inline float rotationAngle() const { return m_rotationAngle; } + inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; } + inline QQuaternion rotation() const { return m_rotation; } inline void setX(float value) { m_position.setX(value); } inline void setY(float value) { m_position.setY(value); } inline void setZ(float value) { m_position.setZ(value); } @@ -58,8 +56,7 @@ protected: private: QVector3D m_position; - QVector3D m_rotationAxis; - float m_rotationAngle; + QQuaternion m_rotation; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp index a1158453..f89fa77c 100644 --- a/src/datavisualization/data/scatteritemmodelhandler.cpp +++ b/src/datavisualization/data/scatteritemmodelhandler.cpp @@ -92,26 +92,39 @@ void ScatterItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int s } } -static inline QVector3D toRotationAxis(const QVariant &variant) +static inline QQuaternion toQuaternion(const QVariant &variant) { - if (variant.canConvert()) { - return variant.value(); + if (variant.canConvert()) { + return variant.value(); } else if (variant.canConvert()) { QString s = variant.toString(); - if (!s.isEmpty() && s.count(QLatin1Char(',')) == 2) { - int index = s.indexOf(QLatin1Char(',')); - int index2 = s.indexOf(QLatin1Char(','), index + 1); - - bool xGood, yGood, zGood; - float xCoord = s.left(index).toFloat(&xGood); - float yCoord = s.mid(index + 1, index2 - index - 1).toFloat(&yGood); - float zCoord = s.mid(index2 + 1).toFloat(&zGood); - - if (xGood && yGood && zGood) - return QVector3D(xCoord, yCoord, zCoord); + if (!s.isEmpty()) { + bool angleAndAxis = false; + if (s.startsWith(QLatin1Char('@'))) { + angleAndAxis = true; + s = s.mid(1); + } + if (s.count(QLatin1Char(',')) == 3) { + int index = s.indexOf(QLatin1Char(',')); + int index2 = s.indexOf(QLatin1Char(','), index + 1); + int index3 = s.indexOf(QLatin1Char(','), index2 + 1); + + bool sGood, xGood, yGood, zGood; + float sCoord = s.left(index).toFloat(&sGood); + float xCoord = s.mid(index + 1, index2 - index - 1).toFloat(&xGood); + float yCoord = s.mid(index2 + 1, index3 - index2 - 1).toFloat(&yGood); + float zCoord = s.mid(index3 + 1).toFloat(&zGood); + + if (sGood && xGood && yGood && zGood) { + if (angleAndAxis) + return QQuaternion::fromAxisAndAngle(xCoord, yCoord, zCoord, sCoord); + else + return QQuaternion(sCoord, xCoord, yCoord, zCoord); + } + } } } - return upVector; + return QQuaternion(); } void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn, @@ -127,10 +140,8 @@ void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColum yPos = index.data(m_yPosRole).toFloat(); if (m_zPosRole != noRoleIndex) zPos = index.data(m_zPosRole).toFloat(); - if (m_rotationAxisRole != noRoleIndex) - item.setRotationAxis(toRotationAxis(index.data(m_rotationAxisRole))); - if (m_rotationAngleRole != noRoleIndex) - item.setRotationAngle(index.data(m_rotationAngleRole).toFloat()); + if (m_rotationRole != noRoleIndex) + item.setRotation(toQuaternion(index.data(m_rotationRole))); item.setPosition(QVector3D(xPos, yPos, zPos)); } @@ -147,8 +158,7 @@ void ScatterItemModelHandler::resolveModel() m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex); m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), noRoleIndex); m_zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex); - m_rotationAxisRole = roleHash.key(m_proxy->rotationAxisRole().toLatin1(), noRoleIndex); - m_rotationAngleRole = roleHash.key(m_proxy->rotationAngleRole().toLatin1(), noRoleIndex); + m_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex); const int columnCount = m_itemModel->columnCount(); const int rowCount = m_itemModel->rowCount(); const int totalCount = rowCount * columnCount; diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h index 5f148434..0661d734 100644 --- a/src/datavisualization/data/scatteritemmodelhandler_p.h +++ b/src/datavisualization/data/scatteritemmodelhandler_p.h @@ -58,8 +58,7 @@ private: int m_xPosRole; int m_yPosRole; int m_zPosRole; - int m_rotationAxisRole; - int m_rotationAngleRole; + int m_rotationRole; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 264d25d0..2c2654e6 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -258,11 +258,6 @@ void Bars3DRenderer::updateData() updateSelectedBar(m_selectedBarPos, m_selectedBarSeries); } -void Bars3DRenderer::updateSeries(const QList &seriesList, bool updateVisibility) -{ - Abstract3DRenderer::updateSeries(seriesList, updateVisibility); -} - void Bars3DRenderer::updateScene(Q3DScene *scene) { if (m_hasNegativeValues) diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index e53f9bc5..89030b30 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -114,7 +114,6 @@ public: ~Bars3DRenderer(); void updateData(); - void updateSeries(const QList &seriesList, bool updateVisibility); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 0c835c77..a2321546 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -210,14 +210,10 @@ void Scatter3DRenderer::updateData() && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) { renderItem.setPosition(dotPos); renderItem.setVisible(true); - float angle = dataArray.at(i).rotationAngle(); - if (angle) { - renderItem.setRotation(QQuaternion::fromAxisAndAngle( - dataArray.at(i).rotationAxis(), - dataArray.at(i).rotationAngle())); - } else { + if (!dataArray.at(i).rotation().isIdentity()) + renderItem.setRotation(dataArray.at(i).rotation().normalized()); + else renderItem.setRotation(identityQuaternion); - } calculateTranslation(renderItem); } else { renderItem.setVisible(false); diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp index 9ce0fe99..1c7e5e80 100644 --- a/src/datavisualization/engine/seriesrendercache.cpp +++ b/src/datavisualization/engine/seriesrendercache.cpp @@ -128,11 +128,11 @@ void SeriesRenderCache::populate(QAbstract3DSeries *series, Abstract3DRenderer * } if (seriesChanged || changeTracker.meshRotationChanged) { - float angle = series->meshRotationAngle(); - if (angle) - m_meshRotation = QQuaternion::fromAxisAndAngle(series->meshRotationAxis(), series->meshRotationAngle()); - else + m_meshRotation = series->meshRotation().normalized(); + if (m_series->type() == QAbstract3DSeries::SeriesTypeBar + && (m_meshRotation.x() || m_meshRotation.z())) { m_meshRotation = identityQuaternion; + } changeTracker.meshRotationChanged = false; } -- cgit v1.2.3