summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-02-07 15:30:53 +0200
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-02-10 08:25:28 +0200
commit61c84e2d9c46de40d22f6fafbdd23d4015025516 (patch)
tree13c04fa5a90e75d5730babd6ab1cefef54b54417
parentffc2e2039f58de256a98da395b5d0e87d5a176fc (diff)
Mostly revert the rotations refactor
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ää <tomi.korpipaa@digia.com>
-rw-r--r--src/datavisualization/data/qabstract3dseries.cpp100
-rw-r--r--src/datavisualization/data/qabstract3dseries.h15
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h6
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp57
-rw-r--r--src/datavisualization/data/qbar3dseries.h5
-rw-r--r--src/datavisualization/data/qbar3dseries_p.h4
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp68
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h17
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h3
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp51
-rw-r--r--src/datavisualization/data/qscatterdataitem.h13
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp52
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h3
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp5
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h1
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp10
-rw-r--r--src/datavisualization/engine/seriesrendercache.cpp8
-rw-r--r--tests/barstest/chart.cpp2
-rw-r--r--tests/directional/scatterdatamodifier.cpp11
-rw-r--r--tests/qmlcamera/qml/qmlcamera/Data.qml2
-rw-r--r--tests/qmldynamicdata/qml/qmldynamicdata/main.qml22
21 files changed, 214 insertions, 241 deletions
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.
*/
/*!
@@ -253,6 +240,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle)
+ *
+ * A convenience function to construct mesh rotation quaternion from axis and angle.
+ *
+ * \sa meshRotation
+ */
+
+/*!
* \internal
*/
QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) :
@@ -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 <QObject>
#include <QScopedPointer>
#include <QLinearGradient>
-#include <QVector3D>
+#include <QQuaternion>
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
@@ -115,6 +115,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \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.
*/
QBar3DSeries::QBar3DSeries(QObject *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 <QtDataVisualization/qdatavisualizationglobal.h>
-#include <QVector3D>
+#include <QQuaternion>
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<QVector3D>()) {
- return variant.value<QVector3D>();
+ if (variant.canConvert<QQuaternion>()) {
+ return variant.value<QQuaternion>();
} else if (variant.canConvert<QString>()) {
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<QAbstract3DSeries *> &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<QAbstract3DSeries *> &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;
}
diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp
index df71a0ed..e7a0e2ca 100644
--- a/tests/barstest/chart.cpp
+++ b/tests/barstest/chart.cpp
@@ -1096,7 +1096,7 @@ void GraphModifier::triggerRotation()
// Rotate the first series instead
static float seriesAngle = 0.0f;
if (m_graph->seriesList().size())
- m_graph->seriesList().at(0)->setMeshRotationAngle(seriesAngle++);
+ m_graph->seriesList().at(0)->setMeshAngle(seriesAngle++);
}
}
diff --git a/tests/directional/scatterdatamodifier.cpp b/tests/directional/scatterdatamodifier.cpp
index 3735e14c..1422cebb 100644
--- a/tests/directional/scatterdatamodifier.cpp
+++ b/tests/directional/scatterdatamodifier.cpp
@@ -111,8 +111,7 @@ void ScatterDataModifier::addData()
#endif
ptrToDataArray->setPosition(QVector3D(x, y, z));
- ptrToDataArray->setRotationAxis(rotation.vector());
- ptrToDataArray->setRotationAngle(qAcos(rotation.scalar()) * 360.0f / M_PI);
+ ptrToDataArray->setRotation(rotation);
ptrToDataArray++;
}
}
@@ -173,13 +172,15 @@ void ScatterDataModifier::triggerRotation()
if (m_graph->seriesList().size()) {
int selectedIndex = m_graph->seriesList().at(0)->selectedItem();
if (selectedIndex != QScatter3DSeries::invalidSelectionIndex()) {
+ static float itemAngle = 0.0f;
QScatterDataItem item(*(m_graph->seriesList().at(0)->dataProxy()->itemAt(selectedIndex)));
- item.setRotationAngle(item.rotationAngle() + 1);
+ QQuaternion itemRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, itemAngle++);
+ item.setRotation(itemRotation);
m_graph->seriesList().at(0)->dataProxy()->setItem(selectedIndex, item);
} else {
static float seriesAngle = 0.0f;
- m_graph->seriesList().at(0)->setMeshRotationAxis(QVector3D(1.0f, 1.0f, 1.0f));
- m_graph->seriesList().at(0)->setMeshRotationAngle(seriesAngle++);
+ QQuaternion rotation = QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 1.0f, seriesAngle++);
+ m_graph->seriesList().at(0)->setMeshRotation(rotation);
}
}
}
diff --git a/tests/qmlcamera/qml/qmlcamera/Data.qml b/tests/qmlcamera/qml/qmlcamera/Data.qml
index ba920ef9..bab6bf78 100644
--- a/tests/qmlcamera/qml/qmlcamera/Data.qml
+++ b/tests/qmlcamera/qml/qmlcamera/Data.qml
@@ -38,7 +38,7 @@ Item {
dataProxy: modelProxy
itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
- onMeshRotationAngleChanged: console.log("angle changed:", angle)
+ onMeshAngleChanged: console.log("angle changed:", angle)
}
ListModel {
diff --git a/tests/qmldynamicdata/qml/qmldynamicdata/main.qml b/tests/qmldynamicdata/qml/qmldynamicdata/main.qml
index 03bf4b2d..ff5ea16d 100644
--- a/tests/qmldynamicdata/qml/qmldynamicdata/main.qml
+++ b/tests/qmldynamicdata/qml/qmldynamicdata/main.qml
@@ -28,8 +28,8 @@ Item {
ListModel {
id: graphModel
- ListElement{ xPos: 0.0; yPos: 0.0; zPos: 0.0; rotationAxis: "1.0,1.0,1.0"; rotationAngle: 45 }
- ListElement{ xPos: 1.0; yPos: 1.0; zPos: 1.0; rotationAxis: "1.0,1.0,1.0"; rotationAngle: 45 }
+ ListElement{ xPos: 0.0; yPos: 0.0; zPos: 0.0; rotation: "0.92388, 0.220942, 0.220942, 0.220942"}
+ ListElement{ xPos: 1.0; yPos: 1.0; zPos: 1.0; rotation: "@45,1.0,1.0,1.0" }
}
Timer {
@@ -38,24 +38,23 @@ Item {
running: true
repeat: true
property bool isIncreasing: true
+ property real rotationAngle: 0
- function generateAngle() {
- return Math.random() * 360
- }
-
- function generateAxis() {
- return Math.random() + "," + Math.random() + "," + Math.random()
+ function generateQuaternion() {
+ return "@" + Math.random() * 360 + "," + Math.random() + "," + Math.random() + "," + Math.random()
}
function appendRow() {
graphModel.append({"xPos": Math.random(),
"yPos": Math.random(),
"zPos": Math.random(),
- "rotationAxis": generateAxis(),
- "rotationAngle": generateAngle()});
+ "rotation": generateQuaternion()
+ });
}
onTriggered: {
+ rotationAngle = rotationAngle + 1
+ scatterSeries.setMeshAxisAndAngle(Qt.vector3d(1,1,1), rotationAngle)
if (isIncreasing) {
appendRow()
appendRow()
@@ -130,8 +129,7 @@ Item {
xPosRole: "xPos"
yPosRole: "yPos"
zPosRole: "zPos"
- rotationAxisRole: "rotationAxis"
- rotationAngleRole: "rotationAngle"
+ rotationRole: "rotation"
}
}
}