diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-01-03 09:14:27 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2019-01-07 16:52:35 +0000 |
commit | 55b52c47030c759f8b38013eb873c0b161d0e426 (patch) | |
tree | 08d97fbd7e45a15dc1ffa7df18119094e8a62997 /src/render/geometry | |
parent | 6f59eb1990d2ad700a109c6407aaef28004e135b (diff) |
QGeometry: add minExtent/maxExtent properties
To allow computing a bounding box for a given QGeometry while waiting
for a proper bounding volume aspect.
Change-Id: If1ecf2f9236beaf569c650e5f8b05a6151ca6381
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/render/geometry')
-rw-r--r-- | src/render/geometry/geometry.cpp | 39 | ||||
-rw-r--r-- | src/render/geometry/geometry_p.h | 10 | ||||
-rw-r--r-- | src/render/geometry/qgeometry.cpp | 56 | ||||
-rw-r--r-- | src/render/geometry/qgeometry.h | 8 | ||||
-rw-r--r-- | src/render/geometry/qgeometry_p.h | 3 |
5 files changed, 114 insertions, 2 deletions
diff --git a/src/render/geometry/geometry.cpp b/src/render/geometry/geometry.cpp index d87b4d8eb..4ee02a74d 100644 --- a/src/render/geometry/geometry.cpp +++ b/src/render/geometry/geometry.cpp @@ -53,8 +53,10 @@ namespace Qt3DRender { namespace Render { Geometry::Geometry() - : BackendNode(ReadOnly) + : BackendNode(ReadWrite) , m_geometryDirty(false) + , m_shouldNotifyMinExtentChanged(false) + , m_shouldNotifyMaxExtentChanged(false) { } @@ -68,6 +70,10 @@ void Geometry::cleanup() m_attributes.clear(); m_geometryDirty = false; m_boundingPositionAttribute = Qt3DCore::QNodeId(); + m_min = QVector3D(); + m_max = QVector3D(); + m_shouldNotifyMinExtentChanged = false; + m_shouldNotifyMaxExtentChanged = false; } void Geometry::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) @@ -122,6 +128,37 @@ void Geometry::unsetDirty() m_geometryDirty = false; } +// Called from calcboundingvolumejob (in a QtConcurrent thead (can't send +// update changes from such a thread)) +void Geometry::updateExtent(const QVector3D &min, const QVector3D &max) +{ + // Send notification to frontend + if (m_min != min) { + m_min = min; + m_shouldNotifyMinExtentChanged = true; + } + + if (m_max != max) { + m_max = max; + m_shouldNotifyMaxExtentChanged = true; + } +} + +// Called from calcboundingvolumejob after all bounding volumes have been +// updated (in an aspect thread) +void Geometry::notifyExtentChanged() +{ + if (m_shouldNotifyMinExtentChanged || m_shouldNotifyMaxExtentChanged) { + auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + change->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes); + change->setPropertyName("extent"); + change->setValue(QVariant::fromValue(QPair<QVector3D, QVector3D>(m_min, m_max))); + notifyObservers(change); + m_shouldNotifyMinExtentChanged = false; + m_shouldNotifyMaxExtentChanged = false; + } +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/geometry/geometry_p.h b/src/render/geometry/geometry_p.h index b158648ad..e66524787 100644 --- a/src/render/geometry/geometry_p.h +++ b/src/render/geometry/geometry_p.h @@ -75,12 +75,22 @@ public: inline Qt3DCore::QNodeId boundingPositionAttribute() const { return m_boundingPositionAttribute; } void unsetDirty(); + inline QVector3D min() const { return m_min; } + inline QVector3D max() const { return m_max; } + + void updateExtent(const QVector3D &min, const QVector3D &max); + void notifyExtentChanged(); + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; QVector<Qt3DCore::QNodeId> m_attributes; bool m_geometryDirty; Qt3DCore::QNodeId m_boundingPositionAttribute; + QVector3D m_min; + QVector3D m_max; + bool m_shouldNotifyMinExtentChanged; + bool m_shouldNotifyMaxExtentChanged; }; } // namespace Render diff --git a/src/render/geometry/qgeometry.cpp b/src/render/geometry/qgeometry.cpp index c49dde822..ec80e2657 100644 --- a/src/render/geometry/qgeometry.cpp +++ b/src/render/geometry/qgeometry.cpp @@ -153,6 +153,28 @@ QGeometry::QGeometry(QGeometryPrivate &dd, QNode *parent) { } +void QGeometry::sceneChangeEvent(const QSceneChangePtr &change) +{ + Q_D(QGeometry); + QPropertyUpdatedChangePtr e = qSharedPointerCast<QPropertyUpdatedChange>(change); + if (e->type() == PropertyUpdated) { + const bool blocked = blockNotifications(true); + if (e->propertyName() == QByteArrayLiteral("extent")) { + const QPair<QVector3D, QVector3D> extent = e->value().value<QPair<QVector3D, QVector3D>>(); + + if (extent.first != d->m_minExtent) { + d->m_minExtent = extent.first; + emit minExtentChanged(extent.first); + } + if (extent.second != d->m_maxExtent) { + d->m_maxExtent = extent.second; + emit maxExtentChanged(d->m_maxExtent); + } + } + blockNotifications(blocked); + } +} + /*! \fn void Qt3DRender::QGeometry::addAttribute(Qt3DRender::QAttribute *attribute) Adds an \a attribute to this geometry. @@ -216,6 +238,40 @@ QAttribute *QGeometry::boundingVolumePositionAttribute() const } /*! + \qmlproperty vector3d Geometry::minExtent + + Holds the vertex with the lowest x, y, z position values. + */ + +/*! + \property QGeometry::minExtent + + Holds the vertex with the lowest x, y, z position values. + */ +QVector3D QGeometry::minExtent() const +{ + Q_D(const QGeometry); + return d->m_minExtent; +} + +/*! + \qmlproperty vector3d Geometry::maxExtent + + Holds the vertex with the highest x, y, z position values. + */ + +/*! + \property QGeometry::maxExtent + + Holds the vertex with the highest x, y, z position values. + */ +QVector3D QGeometry::maxExtent() const +{ + Q_D(const QGeometry); + return d->m_maxExtent; +} + +/*! Returns the list of attributes in this geometry. */ QVector<QAttribute *> QGeometry::attributes() const diff --git a/src/render/geometry/qgeometry.h b/src/render/geometry/qgeometry.h index 0e6f7d68e..61508c7d2 100644 --- a/src/render/geometry/qgeometry.h +++ b/src/render/geometry/qgeometry.h @@ -54,6 +54,8 @@ class QT3DRENDERSHARED_EXPORT QGeometry : public Qt3DCore::QNode { Q_OBJECT Q_PROPERTY(Qt3DRender::QAttribute *boundingVolumePositionAttribute READ boundingVolumePositionAttribute WRITE setBoundingVolumePositionAttribute NOTIFY boundingVolumePositionAttributeChanged) + Q_PROPERTY(QVector3D minExtent READ minExtent NOTIFY minExtentChanged REVISION 13) + Q_PROPERTY(QVector3D maxExtent READ maxExtent NOTIFY maxExtentChanged REVISION 13) public: explicit QGeometry(Qt3DCore::QNode *parent = nullptr); ~QGeometry(); @@ -63,15 +65,19 @@ public: Q_INVOKABLE void removeAttribute(Qt3DRender::QAttribute *attribute); QAttribute *boundingVolumePositionAttribute() const; + QVector3D minExtent() const; + QVector3D maxExtent() const; public Q_SLOTS: void setBoundingVolumePositionAttribute(QAttribute *boundingVolumePositionAttribute); Q_SIGNALS: void boundingVolumePositionAttributeChanged(QAttribute *boundingVolumePositionAttribute); - + void minExtentChanged(const QVector3D &minExtent); + void maxExtentChanged(const QVector3D &maxExtent); protected: explicit QGeometry(QGeometryPrivate &dd, Qt3DCore::QNode *parent = nullptr); + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: Q_DECLARE_PRIVATE(QGeometry) diff --git a/src/render/geometry/qgeometry_p.h b/src/render/geometry/qgeometry_p.h index e07b9ff0d..f53548e43 100644 --- a/src/render/geometry/qgeometry_p.h +++ b/src/render/geometry/qgeometry_p.h @@ -53,6 +53,7 @@ #include <Qt3DRender/private/qt3drender_global_p.h> #include <Qt3DCore/private/qnode_p.h> +#include <QVector3D> QT_BEGIN_NAMESPACE @@ -68,6 +69,8 @@ public: QVector<QAttribute *> m_attributes; QAttribute *m_boundingVolumePositionAttribute; + QVector3D m_minExtent; + QVector3D m_maxExtent; }; struct QGeometryData |