summaryrefslogtreecommitdiffstats
path: root/src/render/jobs
diff options
context:
space:
mode:
authorVolker Enderlein <volker.enderlein@ifm-chemnitz.de>2019-09-30 13:48:44 +0200
committerPaul Lemire <paul.lemire@kdab.com>2019-10-01 16:13:45 +0200
commit851b2189a8d31b9306f696c38988bbc554fa9e0c (patch)
tree48d029dfa9cc63c396092eefecc678c8c8145b52 /src/render/jobs
parentc40cccb0b4485045db61c2d4e825e33a68c58861 (diff)
Fix for bounding volume handling and calculation
- Fixed Ritter algorithm implementation - Added notation of invalid bounding sphere (radius == -1.0) - Handle merging of invalid bounding sphere with valid ones - Added test cases and adjusted tests boundingsphere and proximityfilter - This is necessary to ensure the correct working for viewAll and viewEntity Task-number: QTBUG-78313 Change-Id: I1dc6d227cf9009f6fbd3230093c7a7a94fb05ae3 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/jobs')
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp78
1 files changed, 53 insertions, 25 deletions
diff --git a/src/render/jobs/calcboundingvolumejob.cpp b/src/render/jobs/calcboundingvolumejob.cpp
index 113dc34ce..9af2f4f38 100644
--- a/src/render/jobs/calcboundingvolumejob.cpp
+++ b/src/render/jobs/calcboundingvolumejob.cpp
@@ -90,30 +90,42 @@ public:
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();
- const float zDist2 = (findExtremePoints.zMaxPt - findExtremePoints.zMinPt).lengthSquared();
-
- // Select most distant pair
- Vector3D p = findExtremePoints.xMinPt;
- Vector3D q = findExtremePoints.xMaxPt;
- if (yDist2 > xDist2 && yDist2 > zDist2) {
- p = findExtremePoints.yMinPt;
- q = findExtremePoints.yMaxPt;
+ FindMaxDistantPoint maxDistantPointY(m_manager);
+ maxDistantPointY.setReferencePoint = true;
+ if (!maxDistantPointY.apply(positionAttribute, indexAttribute, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex)) {
+ return false;
}
- if (zDist2 > xDist2 && zDist2 > yDist2) {
- p = findExtremePoints.zMinPt;
- q = findExtremePoints.zMaxPt;
+ if (maxDistantPointY.hasNoPoints)
+ return false;
+
+ //const Vector3D x = maxDistantPointY.referencePt;
+ const Vector3D y = maxDistantPointY.maxDistPt;
+
+ FindMaxDistantPoint maxDistantPointZ(m_manager);
+ maxDistantPointZ.setReferencePoint = false;
+ maxDistantPointZ.referencePt = y;
+ if (!maxDistantPointZ.apply(positionAttribute, indexAttribute, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex)) {
+ return false;
+ }
+ const Vector3D z = maxDistantPointZ.maxDistPt;
+
+ const Vector3D center = (y + z) * 0.5f;
+
+ FindMaxDistantPoint maxDistantPointCenter(m_manager);
+ maxDistantPointCenter.setReferencePoint = false;
+ maxDistantPointCenter.referencePt = center;
+ if (!maxDistantPointCenter.apply(positionAttribute, indexAttribute, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex)) {
+ return false;
}
- const Vector3D c = 0.5f * (p + q);
- m_volume.setCenter(c);
- m_volume.setRadius((q - c).length());
+ const float radius = (center - maxDistantPointCenter.maxDistPt).length();
- ExpandSphere expandSphere(m_manager, m_volume);
- if (!expandSphere.apply(positionAttribute, indexAttribute, drawVertexCount,
- primitiveRestartEnabled, primitiveRestartIndex))
+ m_volume = Qt3DRender::Render::Sphere(center, radius);
+
+ if (m_volume.isNull())
return false;
return true;
@@ -172,18 +184,34 @@ private:
}
};
- class ExpandSphere : public Buffer3fVisitor
+ class FindMaxDistantPoint : public Buffer3fVisitor
{
public:
- ExpandSphere(NodeManagers *manager, Sphere& volume)
- : Buffer3fVisitor(manager), m_volume(volume)
+ FindMaxDistantPoint(NodeManagers *manager)
+ : Buffer3fVisitor(manager)
{ }
- Sphere& m_volume;
+ float maxLengthSquared = 0.0f;
+ Vector3D maxDistPt;
+ Vector3D referencePt;
+ bool setReferencePoint = false;
+ bool hasNoPoints = true;
+
void visit(uint ndx, float x, float y, float z) override
{
Q_UNUSED(ndx);
- m_volume.expandToContain(Vector3D(x, y, z));
+ const Vector3D p = Vector3D(x, y, z);
+
+ if (hasNoPoints && setReferencePoint) {
+ maxLengthSquared = 0.0f;
+ referencePt = p;
+ }
+ const float lengthSquared = (p - referencePt).lengthSquared();
+ if ( lengthSquared >= maxLengthSquared ) {
+ maxDistPt = p;
+ maxLengthSquared = lengthSquared;
+ }
+ hasNoPoints = false;
}
};
};