summaryrefslogtreecommitdiffstats
path: root/src/render/jobs
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-11-10 14:53:14 +0100
committerAndy Nichols <andy.nichols@theqtcompany.com>2015-11-16 12:27:00 +0000
commit06a2a44cbbf15c11e5ba4db68c3d75b43ee5eecc (patch)
treebd488735b011cb9f279d174cb88e340882d88850 /src/render/jobs
parentc91a03ca64ee4e4db1c98d1b007674177b6d9169 (diff)
Updated CalcBoundingVolumeJob: to compute BV only when needed
Change-Id: I864423c8262a7c90fe6cf04b0bcfd5baa1bacef8 Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/render/jobs')
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp73
1 files changed, 50 insertions, 23 deletions
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index b0a30210e..3a2923c1d 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -50,6 +50,7 @@
#include <Qt3DCore/qaxisalignedboundingbox.h>
#include <QtCore/qmath.h>
+#include <QtConcurrent/QtConcurrent>
QT_BEGIN_NAMESPACE
@@ -58,19 +59,26 @@ namespace Render {
namespace {
+void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node);
+
+struct UpdateBoundFunctor {
+ NodeManagers *manager;
+
+ void operator ()(Qt3DRender::Render::Entity *node)
+ {
+ calculateLocalBoundingVolume(manager, node);
+ }
+};
+
void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
{
- // TO DO: How do we set the object picker to dirty when the buffer
- // referenced by the pickVolumeAttribute changes or has its internal buffer
- // data changed
+ // The Bounding volume will only be computed if the position Buffer
+ // isDirty
GeometryRenderer *gRenderer = node->renderComponent<GeometryRenderer>();
if (gRenderer) {
Geometry *geom = manager->lookupResource<Geometry, GeometryManager>(gRenderer->geometryId());
- // TO DO: We must not recompute this every frame
- // Find a way to detect that the bounding volume attribute or its buffer have changed
-
if (geom) {
Qt3DRender::Render::Attribute *pickVolumeAttribute = manager->lookupResource<Attribute, AttributeManager>(geom->boundingPositionAttribute());
@@ -100,28 +108,47 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
return;
}
- const QByteArray buffer = buf->data();
- const char *rawBuffer = buffer.constData();
- rawBuffer += pickVolumeAttribute->byteOffset();
- const int stride = pickVolumeAttribute->byteStride() ? pickVolumeAttribute->byteStride() : sizeof(float) * pickVolumeAttribute->dataSize();
- QVector<QVector3D> vertices(pickVolumeAttribute->count());
-
- for (int c = 0, vC = vertices.size(); c < vC; ++c) {
- QVector3D v;
- const float *fptr = reinterpret_cast<const float*>(rawBuffer);
- for (uint i = 0, m = qMin(pickVolumeAttribute->dataSize(), 3U); i < m; ++i)
- v[i] = fptr[i];
- vertices[c] = v;
- rawBuffer += stride;
+ // Buf will be set to not dirty once it's loaded
+ // in a job executed after this one
+ // We need to recompute the bounding volume
+ // If anything in the GeometryRenderer has changed
+ if (buf->isDirty() ||
+ node->isBoundingVolumeDirty() ||
+ pickVolumeAttribute->isDirty() ||
+ geom->isDirty() ||
+ gRenderer->isDirty()) {
+
+ const QByteArray buffer = buf->data();
+ const char *rawBuffer = buffer.constData();
+ rawBuffer += pickVolumeAttribute->byteOffset();
+ const int stride = pickVolumeAttribute->byteStride() ? pickVolumeAttribute->byteStride() : sizeof(float) * pickVolumeAttribute->dataSize();
+ QVector<QVector3D> vertices(pickVolumeAttribute->count());
+
+ for (int c = 0, vC = vertices.size(); c < vC; ++c) {
+ QVector3D v;
+ const float *fptr = reinterpret_cast<const float*>(rawBuffer);
+ for (uint i = 0, m = qMin(pickVolumeAttribute->dataSize(), 3U); i < m; ++i)
+ v[i] = fptr[i];
+ vertices[c] = v;
+ rawBuffer += stride;
+ }
+
+ node->localBoundingVolume()->initializeFromPoints(vertices);
+ node->unsetBoundingVolumeDirty();
}
-
- node->localBoundingVolume()->initializeFromPoints(vertices);
}
}
}
- Q_FOREACH (Entity *child, node->children())
- calculateLocalBoundingVolume(manager, child);
+ const QVector<Qt3DRender::Render::Entity *> children = node->children();
+ if (children.size() > 1) {
+ UpdateBoundFunctor functor;
+ functor.manager = manager;
+ QtConcurrent::blockingMap(children, functor);
+ } else {
+ Q_FOREACH (Entity *child, node->children())
+ calculateLocalBoundingVolume(manager, child);
+ }
}
} // anonymous