diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-11-10 14:53:14 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-11-16 12:27:00 +0000 |
commit | 06a2a44cbbf15c11e5ba4db68c3d75b43ee5eecc (patch) | |
tree | bd488735b011cb9f279d174cb88e340882d88850 /src/render/jobs | |
parent | c91a03ca64ee4e4db1c98d1b007674177b6d9169 (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.cpp | 73 |
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 |