summaryrefslogtreecommitdiffstats
path: root/src/render/jobs/calcboundingvolumejob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/jobs/calcboundingvolumejob.cpp')
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp58
1 files changed, 45 insertions, 13 deletions
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index 66d59f812..68eb308c5 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -65,14 +65,25 @@ namespace Render {
namespace {
-void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node);
+QVector<Geometry*> calculateLocalBoundingVolume(NodeManagers *manager, Entity *node);
-struct UpdateBoundFunctor {
+struct UpdateBoundFunctor
+{
NodeManagers *manager;
- void operator ()(Qt3DRender::Render::Entity *node)
+ // This define is required to work with QtConcurrent
+ typedef QVector<Geometry *> result_type;
+ QVector<Geometry *> operator ()(Qt3DRender::Render::Entity *node)
+ {
+ return calculateLocalBoundingVolume(manager, node);
+ }
+};
+
+struct ReduceUpdateBoundFunctor
+{
+ void operator ()(QVector<Geometry *> &result, const QVector<Geometry *> &values)
{
- calculateLocalBoundingVolume(manager, node);
+ result += values;
}
};
@@ -82,6 +93,8 @@ public:
BoundingVolumeCalculator(NodeManagers *manager) : m_manager(manager) { }
const Sphere& result() { return m_volume; }
+ const QVector3D min() const { return m_min; }
+ const QVector3D max() const { return m_max; }
bool apply(Qt3DRender::Render::Attribute *positionAttribute,
Qt3DRender::Render::Attribute *indexAttribute,
@@ -95,6 +108,9 @@ public:
return false;
}
+ m_min = QVector3D(findExtremePoints.xMin, findExtremePoints.yMin, findExtremePoints.zMin);
+ m_max = QVector3D(findExtremePoints.xMax, findExtremePoints.yMax, findExtremePoints.zMax);
+
// Calculate squared distance for the pairs of points
const float xDist2 = (findExtremePoints.xMaxPt - findExtremePoints.xMinPt).lengthSquared();
const float yDist2 = (findExtremePoints.yMaxPt - findExtremePoints.yMinPt).lengthSquared();
@@ -127,6 +143,8 @@ public:
private:
Sphere m_volume;
NodeManagers *m_manager;
+ QVector3D m_min;
+ QVector3D m_max;
class FindExtremePoints : public Buffer3fVisitor
{
@@ -191,17 +209,20 @@ private:
};
};
-void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
+QVector<Geometry *> calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
{
// The Bounding volume will only be computed if the position Buffer
// isDirty
+ QVector<Geometry *> updatedGeometries;
+
if (!node->isTreeEnabled())
- return;
+ return updatedGeometries;
GeometryRenderer *gRenderer = node->renderComponent<GeometryRenderer>();
+ GeometryManager *geometryManager = manager->geometryManager();
if (gRenderer && gRenderer->primitiveType() != QGeometryRenderer::Patches) {
- Geometry *geom = manager->lookupResource<Geometry, GeometryManager>(gRenderer->geometryId());
+ Geometry *geom = geometryManager->lookupResource(gRenderer->geometryId());
if (geom) {
int drawVertexCount = gRenderer->vertexCount(); // may be 0, gets changed below if so
@@ -224,14 +245,14 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
|| positionAttribute->vertexBaseType() != QAttribute::Float
|| positionAttribute->vertexSize() < 3) {
qWarning("calculateLocalBoundingVolume: Position attribute not suited for bounding volume computation");
- return;
+ return updatedGeometries;
}
Buffer *buf = manager->lookupResource<Buffer, BufferManager>(positionAttribute->bufferId());
// No point in continuing if the positionAttribute doesn't have a suitable buffer
if (!buf) {
qWarning("calculateLocalBoundingVolume: Position attribute not referencing a valid buffer");
- return;
+ return updatedGeometries;
}
// Check if there is an index attribute.
@@ -259,7 +280,7 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
std::end(validIndexTypes),
indexAttribute->vertexBaseType()) == std::end(validIndexTypes)) {
qWarning() << "calculateLocalBoundingVolume: Unsupported index attribute type" << indexAttribute->name() << indexAttribute->vertexBaseType();
- return;
+ return updatedGeometries;
}
break;
@@ -287,6 +308,11 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
node->localBoundingVolume()->setCenter(reader.result().center());
node->localBoundingVolume()->setRadius(reader.result().radius());
node->unsetBoundingVolumeDirty();
+
+ // Record min/max vertex in Geometry
+ geom->updateExtent(reader.min(), reader.max());
+ // Mark geometry as requiring a call to update its frontend
+ updatedGeometries.push_back(geom);
}
}
}
@@ -297,14 +323,16 @@ void calculateLocalBoundingVolume(NodeManagers *manager, Entity *node)
if (children.size() > 1) {
UpdateBoundFunctor functor;
functor.manager = manager;
- QtConcurrent::blockingMap(children, functor);
+ ReduceUpdateBoundFunctor reduceFunctor;
+ updatedGeometries += QtConcurrent::blockingMappedReduced<decltype(updatedGeometries)>(children, functor, reduceFunctor);
} else
#endif
{
const auto children = node->children();
for (Entity *child : children)
- calculateLocalBoundingVolume(manager, child);
+ updatedGeometries += calculateLocalBoundingVolume(manager, child);
}
+ return updatedGeometries;
}
} // anonymous
@@ -318,7 +346,11 @@ CalculateBoundingVolumeJob::CalculateBoundingVolumeJob()
void CalculateBoundingVolumeJob::run()
{
- calculateLocalBoundingVolume(m_manager, m_node);
+ const QVector<Geometry *> updatedGeometries = calculateLocalBoundingVolume(m_manager, m_node);
+
+ // Send extent updates to frontend
+ for (Geometry *geometry : updatedGeometries)
+ geometry->notifyExtentChanged();
}
void CalculateBoundingVolumeJob::setRoot(Entity *node)