From 811be6f81b2e8c4d9d23cff5b4287c8a5dc86fc3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 6 Feb 2014 14:00:25 +0200 Subject: Change rotations to use angle and vector in APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quaternions are pain in the behind to use, especially in QML, so change them to angle + vector combinations. Change-Id: I25eb5ea92deaf3a079e2e193cce2e8de89f3c3c4 Reviewed-by: Tomi Korpipää --- src/datavisualization/data/abstractrenderitem.cpp | 1 + src/datavisualization/data/abstractrenderitem_p.h | 8 ++ src/datavisualization/data/barrenderitem.cpp | 1 - src/datavisualization/data/barrenderitem_p.h | 4 - src/datavisualization/data/qabstract3dseries.cpp | 94 +++++++++++++++++----- src/datavisualization/data/qabstract3dseries.h | 14 ++-- 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 | 60 ++++++++++---- .../data/qitemmodelscatterdataproxy.h | 18 +++-- .../data/qitemmodelscatterdataproxy_p.h | 3 +- src/datavisualization/data/qscatterdataitem.cpp | 52 +++++++++--- src/datavisualization/data/qscatterdataitem.h | 11 ++- .../data/scatteritemmodelhandler.cpp | 33 ++++---- .../data/scatteritemmodelhandler_p.h | 3 +- src/datavisualization/data/scatterrenderitem.cpp | 1 - src/datavisualization/data/scatterrenderitem_p.h | 8 -- 19 files changed, 221 insertions(+), 162 deletions(-) (limited to 'src/datavisualization/data') diff --git a/src/datavisualization/data/abstractrenderitem.cpp b/src/datavisualization/data/abstractrenderitem.cpp index 522fd144..e22a46d8 100644 --- a/src/datavisualization/data/abstractrenderitem.cpp +++ b/src/datavisualization/data/abstractrenderitem.cpp @@ -29,6 +29,7 @@ AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other) { m_selectionLabel = other.m_selectionLabel; m_translation = other.m_translation; + m_rotation = other.m_rotation; m_selectionLabelItem = 0; } diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h index fa06db54..8d2fab8a 100644 --- a/src/datavisualization/data/abstractrenderitem_p.h +++ b/src/datavisualization/data/abstractrenderitem_p.h @@ -57,10 +57,18 @@ public: void setSelectionLabel(const QString &label); QString &selectionLabel(); // Formats selection label if not previously formatted + inline QQuaternion rotation() const { return m_rotation; } + inline void setRotation(const QQuaternion &rotation) + { + if (m_rotation != rotation) + m_rotation = rotation; + } + protected: QString m_selectionLabel; QVector3D m_translation; LabelItem *m_selectionLabelItem; + QQuaternion m_rotation; friend class QAbstractDataItem; }; diff --git a/src/datavisualization/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp index 915f3f78..869dac2e 100644 --- a/src/datavisualization/data/barrenderitem.cpp +++ b/src/datavisualization/data/barrenderitem.cpp @@ -39,7 +39,6 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other) m_sliceLabel = other.m_sliceLabel; m_sliceLabelItem = 0; m_seriesIndex = other.m_seriesIndex; - m_rotation = other.m_rotation; } BarRenderItem::~BarRenderItem() diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h index e1062969..df9d7a60 100644 --- a/src/datavisualization/data/barrenderitem_p.h +++ b/src/datavisualization/data/barrenderitem_p.h @@ -74,9 +74,6 @@ public: inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; } inline int seriesIndex() const { return m_seriesIndex; } - inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; } - inline const QQuaternion &rotation() const { return m_rotation; } - protected: float m_value; QPoint m_position; // x = row, y = column @@ -84,7 +81,6 @@ protected: QString m_sliceLabel; LabelItem *m_sliceLabelItem; int m_seriesIndex; - QQuaternion m_rotation; friend class QBarDataItem; }; diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp index dc241fdb..fbc72410 100644 --- a/src/datavisualization/data/qabstract3dseries.cpp +++ b/src/datavisualization/data/qabstract3dseries.cpp @@ -142,15 +142,28 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! - * \qmlproperty quaternion Abstract3DSeries::meshRotation + * \qmlproperty vector3d Abstract3DSeries::meshRotationAxis * - * 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. + * 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. * Surface3DSeries applies the rotation only to the selection pointer. - * Defaults to no rotation. + * 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 */ /*! @@ -351,27 +364,54 @@ bool QAbstract3DSeries::isMeshSmooth() const } /*! - * \property QAbstract3DSeries::meshRotation + * \property QAbstract3DSeries::meshRotationAxis + * + * 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. + * QSurface3DSeries applies the rotation only to the selection pointer. + * Defaults to Y-axis. + * + * \sa meshRotationAngle + */ +void QAbstract3DSeries::setMeshRotationAxis(const QVector3D &axis) +{ + if (d_ptr->m_type != SeriesTypeBar) { + if (d_ptr->m_meshRotationAxis != axis) { + d_ptr->setMeshRotationAxis(axis); + emit meshRotationAxisChanged(axis); + } + } +} + +QVector3D QAbstract3DSeries::meshRotationAxis() const +{ + return d_ptr->m_meshRotationAxis; +} + +/*! + * \property QAbstract3DSeries::meshRotationAngle * - * 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. + * 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 no rotation. + * Defaults to 0. + * + * \sa meshRotationAxis */ -void QAbstract3DSeries::setMeshRotation(const QQuaternion &rotation) +void QAbstract3DSeries::setMeshRotationAngle(float angle) { - if (d_ptr->m_meshRotation != rotation) { - d_ptr->setMeshRotation(rotation); - emit meshRotationChanged(rotation); + if (d_ptr->m_meshRotationAngle != angle) { + d_ptr->setMeshRotationAngle(angle); + emit meshRotationAngleChanged(angle); } } -QQuaternion QAbstract3DSeries::meshRotation() const +float QAbstract3DSeries::meshRotationAngle() const { - return d_ptr->m_meshRotation; + return d_ptr->m_meshRotationAngle; } /*! @@ -579,6 +619,8 @@ 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) { } @@ -645,9 +687,17 @@ void QAbstract3DSeriesPrivate::setMeshSmooth(bool enable) m_controller->markSeriesVisualsDirty(); } -void QAbstract3DSeriesPrivate::setMeshRotation(const QQuaternion &rotation) +void QAbstract3DSeriesPrivate::setMeshRotationAxis(const QVector3D &axis) +{ + m_meshRotationAxis = axis; + m_changeTracker.meshRotationChanged = true; + if (m_controller) + m_controller->markSeriesVisualsDirty(); +} + +void QAbstract3DSeriesPrivate::setMeshRotationAngle(float angle) { - m_meshRotation = rotation; + m_meshRotationAngle = angle; 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 c45bb801..b0396126 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,7 +39,8 @@ 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(QQuaternion meshRotation READ meshRotation WRITE setMeshRotation NOTIFY meshRotationChanged) + Q_PROPERTY(QVector3D meshRotationAxis READ meshRotationAxis WRITE setMeshRotationAxis NOTIFY meshRotationAxisChanged) + Q_PROPERTY(float meshRotationAngle READ meshRotationAngle WRITE setMeshRotationAngle NOTIFY meshRotationAngleChanged) 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) @@ -93,8 +94,10 @@ public: void setMeshSmooth(bool enable); bool isMeshSmooth() const; - void setMeshRotation(const QQuaternion &rotation); - QQuaternion meshRotation() const; + void setMeshRotationAxis(const QVector3D &axis); + QVector3D meshRotationAxis() const; + void setMeshRotationAngle(float angle); + float meshRotationAngle() const; void setUserDefinedMesh(const QString &fileName); QString userDefinedMesh() const; @@ -122,7 +125,8 @@ signals: void visibilityChanged(bool visible); void meshChanged(Mesh mesh); void meshSmoothChanged(bool enabled); - void meshRotationChanged(QQuaternion rotation); + void meshRotationAxisChanged(QVector3D axis); + void meshRotationAngleChanged(float angle); 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 6fbabd3d..3c9a9582 100644 --- a/src/datavisualization/data/qabstract3dseries_p.h +++ b/src/datavisualization/data/qabstract3dseries_p.h @@ -108,7 +108,8 @@ public: void setVisible(bool visible); void setMesh(QAbstract3DSeries::Mesh mesh); void setMeshSmooth(bool enable); - void setMeshRotation(const QQuaternion &rotation); + void setMeshRotationAxis(const QVector3D &axis); + void setMeshRotationAngle(float angle); void setUserDefinedMesh(const QString &meshFile); void setColorStyle(Q3DTheme::ColorStyle style); @@ -132,7 +133,8 @@ public: Abstract3DController *m_controller; QAbstract3DSeries::Mesh m_mesh; bool m_meshSmooth; - QQuaternion m_meshRotation; + QVector3D m_meshRotationAxis; + float m_meshRotationAngle; QString m_userDefinedMesh; Q3DTheme::ColorStyle m_colorStyle; diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp index 0616d4e4..124f996b 100644 --- a/src/datavisualization/data/qbar3dseries.cpp +++ b/src/datavisualization/data/qbar3dseries.cpp @@ -114,17 +114,6 @@ 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 and - * always returns a value from zero to 360 degrees. It may also have small rounding errors. - * - * \sa Abstract3DSeries::meshRotation - */ - /*! * Constructs QBar3DSeries with the given \a parent. */ @@ -133,7 +122,6 @@ QBar3DSeries::QBar3DSeries(QObject *parent) : { // Default proxy dptr()->setDataProxy(new QBarDataProxy); - dptr()->connectSignals(); } /*! @@ -143,7 +131,6 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent) { dptr()->setDataProxy(dataProxy); - dptr()->connectSignals(); } /*! @@ -152,7 +139,6 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) : QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) : QAbstract3DSeries(d, parent) { - dptr()->connectSignals(); } /*! @@ -219,38 +205,6 @@ 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 - * and always returns a value from zero to 360 degrees. It may also have small rounding errors. - * - * \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 */ @@ -326,11 +280,6 @@ 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) { @@ -339,10 +288,4 @@ 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 aa67dadb..be748516 100644 --- a/src/datavisualization/data/qbar3dseries.h +++ b/src/datavisualization/data/qbar3dseries.h @@ -32,7 +32,6 @@ 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); @@ -46,13 +45,9 @@ 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 718f1237..173f1cd9 100644 --- a/src/datavisualization/data/qbar3dseries_p.h +++ b/src/datavisualization/data/qbar3dseries_p.h @@ -44,12 +44,8 @@ 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 489f8da7..b73538e9 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp @@ -93,9 +93,15 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! - * \qmlproperty string ItemModelScatterDataProxy::rotationRole + * \qmlproperty string ItemModelScatterDataProxy::rotationAxisRole * - * Defines the rotation role for the mapping. + * Defines the rotation axis role for the mapping. + */ + +/*! + * \qmlproperty string ItemModelScatterDataProxy::rotationAngleRole + * + * Defines the rotation angle role for the mapping. */ /*! @@ -143,13 +149,15 @@ 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, and rotationRole property to \a rotationRole. + * to \a zPosRole, rotationAxisRole property to \a rotationAxisRole, and rotationAngleRole + * property to \a rotationAngleRole. */ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, - const QString &rotationRole, + const QString &rotationAxisRole, + const QString &rotationAngleRole, QObject *parent) : QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent) { @@ -157,7 +165,8 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel dptr()->m_xPosRole = xPosRole; dptr()->m_yPosRole = yPosRole; dptr()->m_zPosRole = zPosRole; - dptr()->m_rotationRole = rotationRole; + dptr()->m_rotationAxisRole = rotationAxisRole; + dptr()->m_rotationAngleRole = rotationAngleRole; dptr()->connectItemModelHandler(); } @@ -239,32 +248,53 @@ QString QItemModelScatterDataProxy::zPosRole() const } /*! - * \property QItemModelScatterDataProxy::rotationRole + * \property QItemModelScatterDataProxy::rotationAxisRole + * + * 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. */ -void QItemModelScatterDataProxy::setRotationRole(const QString &role) +void QItemModelScatterDataProxy::setRotationAngleRole(const QString &role) { - if (dptr()->m_rotationRole != role) { - dptr()->m_rotationRole = role; - emit rotationRoleChanged(role); + if (dptr()->m_rotationAngleRole != role) { + dptr()->m_rotationAngleRole = role; + emit rotationAngleRoleChanged(role); } } -QString QItemModelScatterDataProxy::rotationRole() const +QString QItemModelScatterDataProxy::rotationAngleRole() const { - return dptrc()->m_rotationRole; + return dptrc()->m_rotationAngleRole; } /*! - * Changes \a xPosRole, \a yPosRole and \a zPosRole mapping. + * Changes \a xPosRole, \a yPosRole, \a zPosRole, \a rotationAxis, and \a rotationAngle mapping. */ void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole, - const QString &zPosRole) + const QString &zPosRole, const QString &rotationAxis, + const QString &rotationAngle) { setXPosRole(xPosRole); setYPosRole(yPosRole); setZPosRole(zPosRole); + setRotationAxisRole(rotationAxis); + setRotationAngleRole(rotationAngle); } /*! diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h index accfeb18..ec2deee2 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h @@ -34,7 +34,8 @@ 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 rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged) + Q_PROPERTY(QString rotationAxisRole READ rotationAxisRole WRITE setRotationAxisRole NOTIFY rotationAxisRoleChanged) + Q_PROPERTY(QString rotationAngleRole READ rotationAngleRole WRITE setRotationAngleRole NOTIFY rotationAngleRoleChanged) public: explicit QItemModelScatterDataProxy(QObject *parent = 0); @@ -44,7 +45,8 @@ public: const QString &zPosRole, QObject *parent = 0); QItemModelScatterDataProxy(const QAbstractItemModel *itemModel, const QString &xPosRole, const QString &yPosRole, - const QString &zPosRole, const QString &rotationRole, + const QString &zPosRole, const QString &rotationAxisRole, + const QString &rotationAngleRole, QObject *parent = 0); virtual ~QItemModelScatterDataProxy(); @@ -57,17 +59,21 @@ public: QString yPosRole() const; void setZPosRole(const QString &role); QString zPosRole() const; - void setRotationRole(const QString &role); - QString rotationRole() const; + void setRotationAxisRole(const QString &role); + QString rotationAxisRole() const; + void setRotationAngleRole(const QString &role); + QString rotationAngleRole() const; - void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole); + void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole, + const QString &rotationAxis, const QString &rotationAngle); signals: void itemModelChanged(const QAbstractItemModel* itemModel); void xPosRoleChanged(QString role); void yPosRoleChanged(QString role); void zPosRoleChanged(QString role); - void rotationRoleChanged(QString role); + void rotationAxisRoleChanged(QString role); + void rotationAngleRoleChanged(QString role); protected: QItemModelScatterDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h index 4e1f321f..7057c910 100644 --- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h +++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h @@ -52,7 +52,8 @@ private: QString m_xPosRole; QString m_yPosRole; QString m_zPosRole; - QString m_rotationRole; + QString m_rotationAxisRole; + QString m_rotationAngleRole; friend class ScatterItemModelHandler; friend class QItemModelScatterDataProxy; diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp index 33f8bed0..43b52041 100644 --- a/src/datavisualization/data/qscatterdataitem.cpp +++ b/src/datavisualization/data/qscatterdataitem.cpp @@ -37,7 +37,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * Constructs QScatterDataItem. */ QScatterDataItem::QScatterDataItem() - : d_ptr(0) // private data doesn't exist by default (optimization) + : d_ptr(0), // private data doesn't exist by default (optimization) + m_rotationAxis(upVector), + m_rotationAngle(0.0f) { } @@ -47,7 +49,18 @@ QScatterDataItem::QScatterDataItem() */ QScatterDataItem::QScatterDataItem(const QVector3D &position) : d_ptr(0), - m_position(position) + m_position(position), + m_rotationAxis(upVector), + m_rotationAngle(0.0f) +{ +} + +QScatterDataItem::QScatterDataItem(const QVector3D &position, const QVector3D &rotationAxis, + float rotationAngle) + : d_ptr(0), + m_position(position), + m_rotationAxis(rotationAxis), + m_rotationAngle(rotationAngle) { } @@ -72,7 +85,8 @@ QScatterDataItem::~QScatterDataItem() QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) { m_position = other.m_position; - m_rotation = other.m_rotation; + m_rotationAxis = other.m_rotationAxis; + m_rotationAngle = other.m_rotationAngle; if (other.d_ptr) createExtraData(); @@ -93,17 +107,35 @@ QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) */ /*! - * \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. + * \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. * Defaults to no rotation. + * + * \sa setRotationAxis() */ /*! - * \fn QQuaternion QScatterDataItem::rotation() const - * \return rotation of this data item. - * \sa setRotation() + * \fn float QScatterDataItem::rotationAngle() const + * \return rotation angle of this data item. + * \sa setRotationAxis(), setRotationAngle() */ /*! diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h index d2ef3bcc..64337631 100644 --- a/src/datavisualization/data/qscatterdataitem.h +++ b/src/datavisualization/data/qscatterdataitem.h @@ -22,7 +22,6 @@ #include #include -#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -33,6 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatterDataItem public: QScatterDataItem(); QScatterDataItem(const QVector3D &position); + QScatterDataItem(const QVector3D &position, const QVector3D &rotationAxis, float rotationAngle); QScatterDataItem(const QScatterDataItem &other); ~QScatterDataItem(); @@ -40,8 +40,10 @@ public: inline void setPosition(const QVector3D &position) { m_position = position; } inline QVector3D position() const { return m_position; } - inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; } - inline QQuaternion rotation() const { return m_rotation; } + 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 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); } @@ -56,7 +58,8 @@ protected: private: QVector3D m_position; - QQuaternion m_rotation; + QVector3D m_rotationAxis; + float m_rotationAngle; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp index 1b1aaefe..a1158453 100644 --- a/src/datavisualization/data/scatteritemmodelhandler.cpp +++ b/src/datavisualization/data/scatteritemmodelhandler.cpp @@ -92,28 +92,26 @@ void ScatterItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int s } } -static inline QQuaternion toQuaternion(const QVariant &variant) +static inline QVector3D toRotationAxis(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(',')) == 3) { + if (!s.isEmpty() && s.count(QLatin1Char(',')) == 2) { 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); + 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 (sGood && xGood && yGood && zGood) - return QQuaternion(sCoord, xCoord, yCoord, zCoord); + if (xGood && yGood && zGood) + return QVector3D(xCoord, yCoord, zCoord); } } - return QQuaternion(); + return upVector; } void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn, @@ -129,8 +127,10 @@ 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_rotationRole != noRoleIndex) - item.setRotation(toQuaternion(index.data(m_rotationRole))); + if (m_rotationAxisRole != noRoleIndex) + item.setRotationAxis(toRotationAxis(index.data(m_rotationAxisRole))); + if (m_rotationAngleRole != noRoleIndex) + item.setRotationAngle(index.data(m_rotationAngleRole).toFloat()); item.setPosition(QVector3D(xPos, yPos, zPos)); } @@ -147,7 +147,8 @@ 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_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex); + m_rotationAxisRole = roleHash.key(m_proxy->rotationAxisRole().toLatin1(), noRoleIndex); + m_rotationAngleRole = roleHash.key(m_proxy->rotationAngleRole().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 0661d734..5f148434 100644 --- a/src/datavisualization/data/scatteritemmodelhandler_p.h +++ b/src/datavisualization/data/scatteritemmodelhandler_p.h @@ -58,7 +58,8 @@ private: int m_xPosRole; int m_yPosRole; int m_zPosRole; - int m_rotationRole; + int m_rotationAxisRole; + int m_rotationAngleRole; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp index d39af816..3b2e64c5 100644 --- a/src/datavisualization/data/scatterrenderitem.cpp +++ b/src/datavisualization/data/scatterrenderitem.cpp @@ -33,7 +33,6 @@ ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other) m_visible(false) { m_position = other.m_position; - m_rotation = other.m_rotation; } ScatterRenderItem::~ScatterRenderItem() diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h index 45066dd8..8b560c89 100644 --- a/src/datavisualization/data/scatterrenderitem_p.h +++ b/src/datavisualization/data/scatterrenderitem_p.h @@ -53,19 +53,11 @@ public: } } - inline QQuaternion rotation() const { return m_rotation; } - inline void setRotation(const QQuaternion &rotation) - { - if (m_rotation != rotation) - m_rotation = rotation; - } - inline bool isVisible() const { return m_visible; } inline void setVisible(bool visible) { m_visible = visible; } protected: QVector3D m_position; - QQuaternion m_rotation; bool m_visible; friend class QScatterDataItem; -- cgit v1.2.3