summaryrefslogtreecommitdiffstats
path: root/src/render/geometry
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-01-03 09:14:27 +0100
committerMike Krus <mike.krus@kdab.com>2019-01-07 16:52:35 +0000
commit55b52c47030c759f8b38013eb873c0b161d0e426 (patch)
tree08d97fbd7e45a15dc1ffa7df18119094e8a62997 /src/render/geometry
parent6f59eb1990d2ad700a109c6407aaef28004e135b (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.cpp39
-rw-r--r--src/render/geometry/geometry_p.h10
-rw-r--r--src/render/geometry/qgeometry.cpp56
-rw-r--r--src/render/geometry/qgeometry.h8
-rw-r--r--src/render/geometry/qgeometry_p.h3
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