summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--src/render/frontend/sphere.cpp50
-rw-r--r--src/render/frontend/sphere_p.h13
-rw-r--r--src/render/jobs/calcboundingvolumejob.cpp78
-rw-r--r--tests/auto/render/boundingsphere/tst_boundingsphere.cpp172
-rw-r--r--tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp38
5 files changed, 299 insertions, 52 deletions
diff --git a/src/render/frontend/sphere.cpp b/src/render/frontend/sphere.cpp
index 4909acaef..470dbfe59 100644
--- a/src/render/frontend/sphere.cpp
+++ b/src/render/frontend/sphere.cpp
@@ -44,6 +44,7 @@
#include <QPair>
#include <math.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -55,6 +56,9 @@ namespace {
// returns true and intersection point q; false otherwise
bool intersectRaySphere(const Qt3DRender::RayCasting::QRay3D &ray, const Qt3DRender::Render::Sphere &s, Vector3D *q = nullptr)
{
+ if (s.isNull())
+ return false;
+
const Vector3D p = ray.origin();
const Vector3D d = ray.direction();
const Vector3D m = p - s.center();
@@ -139,11 +143,31 @@ inline void sphereFromExtremePoints(Qt3DRender::Render::Sphere &s, const QVector
inline void constructRitterSphere(Qt3DRender::Render::Sphere &s, const QVector<Vector3D> &points)
{
- // Calculate the sphere encompassing two axially extreme points
- sphereFromExtremePoints(s, points);
-
- // Now make sure the sphere bounds all points by growing if needed
- s.expandToContain(points);
+ //def bounding_sphere(points):
+ // dist = lambda a,b: ((a[0] - b[0])**2 + (a[1] - b[1])**2 + (a[2] - b[2])**2)**0.5
+ // x = points[0]
+ // y = max(points,key= lambda p: dist(p,x) )
+ // z = max(points,key= lambda p: dist(p,y) )
+ // bounding_sphere = (((y[0]+z[0])/2,(y[1]+z[1])/2,(y[2]+z[2])/2), dist(y,z)/2)
+ //
+ // exterior_points = [p for p in points if dist(p,bounding_sphere[0]) > bounding_sphere[1] ]
+ // while ( len(exterior_points) > 0 ):
+ // pt = exterior_points.pop()
+ // if (dist(pt, bounding_sphere[0]) > bounding_sphere[1]):
+ // bounding_sphere = (bounding_sphere[0],dist(pt,bounding_sphere[0]))
+ //
+ // return bounding_sphere
+
+ const Vector3D x = points[0];
+ const Vector3D y = *std::max_element(points.begin(), points.end(), [&x](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - x).lengthSquared() < (rhs - x).lengthSquared(); });
+ const Vector3D z = *std::max_element(points.begin(), points.end(), [&y](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - y).lengthSquared() < (rhs - y).lengthSquared(); });
+
+ const Vector3D center = (y + z) * 0.5f;
+ const Vector3D maxDistPt = *std::max_element(points.begin(), points.end(), [&center](const Vector3D& lhs, const Vector3D& rhs){ return (lhs - center).lengthSquared() < (rhs - center).lengthSquared(); });
+ const float radius = (maxDistPt - center).length();
+
+ s.setCenter(center);
+ s.setRadius(radius);
}
} // anonymous namespace
@@ -169,6 +193,12 @@ void Sphere::initializeFromPoints(const QVector<Vector3D> &points)
void Sphere::expandToContain(const Vector3D &p)
{
+ if (isNull()) {
+ m_center = p;
+ m_radius = 0.0f;
+ return;
+ }
+
const Vector3D d = p - m_center;
const float dist2 = d.lengthSquared();
@@ -184,6 +214,13 @@ void Sphere::expandToContain(const Vector3D &p)
void Sphere::expandToContain(const Sphere &sphere)
{
+ if (isNull()) {
+ *this = sphere;
+ return;
+ } else if (sphere.isNull()) {
+ return;
+ }
+
const Vector3D d(sphere.m_center - m_center);
const float dist2 = d.lengthSquared();
@@ -206,6 +243,9 @@ void Sphere::expandToContain(const Sphere &sphere)
Sphere Sphere::transformed(const Matrix4x4 &mat) const
{
+ if (isNull())
+ return *this;
+
// Transform extremities in x, y, and z directions to find extremities
// of the resulting ellipsoid
Vector3D x = mat.map(m_center + Vector3D(m_radius, 0.0f, 0.0f));
diff --git a/src/render/frontend/sphere_p.h b/src/render/frontend/sphere_p.h
index 10cf92091..b7585f85a 100644
--- a/src/render/frontend/sphere_p.h
+++ b/src/render/frontend/sphere_p.h
@@ -69,7 +69,7 @@ class Q_3DRENDERSHARED_PRIVATE_EXPORT Sphere : public RayCasting::BoundingSphere
public:
inline Sphere(Qt3DCore::QNodeId i = Qt3DCore::QNodeId())
: m_center()
- , m_radius(0.0f)
+ , m_radius(-1.0f)
, m_id(i)
{}
@@ -82,7 +82,7 @@ public:
void setCenter(const Vector3D &c);
Vector3D center() const override;
- inline bool isNull() { return m_center == Vector3D() && m_radius == 0.0f; }
+ bool isNull() const { return m_center == Vector3D() && m_radius == -1.0f; }
void setRadius(float r);
float radius() const override;
@@ -131,7 +131,9 @@ inline Vector3D Sphere::center() const
inline void Sphere::setRadius(float r)
{
- m_radius = r;
+ Q_ASSERT(r >= 0.0f);
+ if (r >= 0.0f)
+ m_radius = r;
}
inline float Sphere::radius() const
@@ -142,11 +144,14 @@ inline float Sphere::radius() const
inline void Sphere::clear()
{
m_center = Vector3D();
- m_radius = 0.0f;
+ m_radius = -1.0f;
}
inline bool intersects(const Sphere &a, const Sphere &b)
{
+ if (a.isNull() || b.isNull())
+ return false;
+
// Calculate squared distance between sphere centers
const Vector3D d = a.center() - b.center();
const float distSq = Vector3D::dotProduct(d, d);
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;
}
};
};
diff --git a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
index 40d992347..0379c883e 100644
--- a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
+++ b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
@@ -169,13 +169,150 @@ class tst_BoundingSphere : public Qt3DCore::QBackendNodeTester
private:
private Q_SLOTS:
+ void checkIsNull() {
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ QVERIFY(defaultSphere.isNull());
+ }
+
+ void remainsNotNullAfterTransform() {
+ QMatrix4x4 mat;
+ mat.translate(-5,-5,-5);
+ auto mMat = Matrix4x4(mat);
+ auto pointSphere = Qt3DRender::Render::Sphere(Vector3D(5.f,5.f,5.f),0.f);
+ pointSphere.transform(mMat);
+ QVERIFY(!pointSphere.isNull());
+ QVERIFY(pointSphere.center() == Vector3D(0.,0.,0));
+ QVERIFY(pointSphere.radius() == 0.f);
+ }
+
+ void remainsNullAfterTransform() {
+ QMatrix4x4 mat;
+ mat.translate(-5,-5,-5);
+ auto mMat = Matrix4x4(mat);
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ defaultSphere.transform(mMat);
+ QVERIFY(defaultSphere.isNull());
+ }
+
+ void expandToContainSphere() {
+ auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
+ auto secondValidSphere = Qt3DRender::Render::Sphere(Vector3D(10.f,10.f,10.f),1.f);
+ firstValidSphere.expandToContain(secondValidSphere);
+ QVERIFY(firstValidSphere.center()==Vector3D(0.f,0.f,0.f));
+ float dist = static_cast<float>((2 + sqrt(3.*(20)*(20)))/2.);
+ QVERIFY(qFuzzyCompare(firstValidSphere.radius(), dist));
+ }
+
+ void expandToContainSphereOneInvalid() {
+ auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ auto copiedSphere = firstValidSphere;
+ firstValidSphere.expandToContain(defaultSphere);
+ QVERIFY(firstValidSphere.center() == copiedSphere.center());
+ QVERIFY(firstValidSphere.radius() == copiedSphere.radius());
+ QVERIFY(!firstValidSphere.isNull());
+ }
+
+ void expandToContainOtherSphereInvalid() {
+ auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ defaultSphere.expandToContain(firstValidSphere);
+ QVERIFY(defaultSphere.center() == firstValidSphere.center());
+ QVERIFY(defaultSphere.radius() == firstValidSphere.radius());
+ QVERIFY(!defaultSphere.isNull());
+ }
+
+ void expandNullSphereWithNullSphere() {
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ auto otherDefaultSphere = Qt3DRender::Render::Sphere();
+ defaultSphere.expandToContain(otherDefaultSphere);
+ QVERIFY(defaultSphere.isNull());
+ }
+
+ void expandToContainPoint() {
+ auto firstValidSphere = Qt3DRender::Render::Sphere(Vector3D(-10.f,-10.f,-10.f),1.f);
+ firstValidSphere.expandToContain(Vector3D(0,0,0));
+ QVERIFY(!firstValidSphere.isNull());
+ float expectedRadius = static_cast<float>((1 + qSqrt(3.*(10)*(10)))/2.);
+ QVERIFY(qFuzzyCompare(firstValidSphere.radius(), expectedRadius));
+ }
+
+ void nullSphereExpandToContainPoint() {
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ defaultSphere.expandToContain(Vector3D(5,5,5));
+ QVERIFY(!defaultSphere.isNull());
+ QVERIFY(defaultSphere.center() == Vector3D(5,5,5));
+ QVERIFY(qFuzzyIsNull(defaultSphere.radius()));
+ }
+
+ void nullSphereExpandToOrigin() {
+ auto defaultSphere = Qt3DRender::Render::Sphere();
+ defaultSphere.expandToContain(Vector3D(0,0,0));
+ QVERIFY(!defaultSphere.isNull());
+ QVERIFY(defaultSphere.center() == Vector3D(0,0,0));
+ QVERIFY(qFuzzyIsNull(defaultSphere.radius()));
+ }
+
+ void ritterSphereCubePoints() {
+ QVector<Vector3D> cubePts={
+ Vector3D(-0.5, -0.5, 0.5),
+ Vector3D( 0.5, -0.5, -0.5),
+ Vector3D(-0.5, 0.5, -0.5),
+ Vector3D( 0.5, 0.5, -0.5),
+ Vector3D(-0.5, -0.5, -0.5),
+ Vector3D( 0.5, -0.5, 0.5),
+ Vector3D(-0.5, 0.5, 0.5),
+ Vector3D( 0.5, 0.5, 0.5)
+ };
+ auto ritterSphere=Qt3DRender::Render::Sphere::fromPoints(cubePts);
+ QVERIFY(!ritterSphere.isNull());
+ QVERIFY(qFuzzyIsNull(ritterSphere.center().x()));
+ QVERIFY(qFuzzyIsNull(ritterSphere.center().y()));
+ QVERIFY(qFuzzyIsNull(ritterSphere.center().z()));
+ QVERIFY(qFuzzyCompare(ritterSphere.radius(), static_cast<float>(qSqrt(3)/2)));
+ }
+
+ void ritterSphereRandomPoints() {
+ QVector<Vector3D> randomPts={
+ Vector3D(-81, 55, 46),
+ Vector3D(-91, -73, -42),
+ Vector3D(-50, -76, -77),
+ Vector3D(-40, 63, 58),
+ Vector3D(-28, -2, -57),
+ Vector3D(84, 17, 33),
+ Vector3D(53, 11, -49),
+ Vector3D(-7, -24, -86),
+ Vector3D(-89, 6, 76),
+ Vector3D(46, -18, -27)
+ };
+
+ auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(randomPts);
+ QVERIFY(!ritterSphere.isNull());
+ QVERIFY(qFuzzyCompare(ritterSphere.center().x(), 17.f));
+ QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -29.5f));
+ QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -22.0f));
+ QVERIFY(qFuzzyCompare(ritterSphere.radius(), 148.66152831179963f));
+ }
+
+ void ritterSphereOnePoint() {
+ QVector<Vector3D> singlePt={
+ Vector3D(-0.5, -0.5, -0.5),
+ };
+ auto ritterSphere = Qt3DRender::Render::Sphere::fromPoints(singlePt);
+ QVERIFY(!ritterSphere.isNull());
+ QVERIFY(qFuzzyCompare(ritterSphere.center().x(), -0.5f));
+ QVERIFY(qFuzzyCompare(ritterSphere.center().y(), -0.5f));
+ QVERIFY(qFuzzyCompare(ritterSphere.center().z(), -0.5f));
+ QVERIFY(qFuzzyIsNull(ritterSphere.radius()));
+ }
+
void checkExtraGeometries_data()
{
QTest::addColumn<QString>("qmlFile");
QTest::addColumn<QVector3D>("sphereCenter");
QTest::addColumn<float>("sphereRadius");
QTest::newRow("SphereMesh") << "qrc:/sphere.qml" << QVector3D(0.f, 0.f, 0.f) << 1.f;
- QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.0928356f, -0.212021f, -0.0467958f) << 1.07583f; // weird!
+ QTest::newRow("CubeMesh") << "qrc:/cube.qml" << QVector3D(0.f, 0.f, 0.f) << static_cast<float>(qSqrt(3.)/2.); // not weird at all
}
void checkExtraGeometries()
@@ -200,9 +337,10 @@ private Q_SLOTS:
const auto boundingSphere = test->sceneRoot()->worldBoundingVolumeWithChildren();
qDebug() << qmlFile << boundingSphere->radius() << boundingSphere->center();
QCOMPARE(boundingSphere->radius(), sphereRadius);
- QVERIFY(qAbs(boundingSphere->center().x() - sphereCenter.x()) < 0.000001f); // qFuzzyCompare hates 0s
- QVERIFY(qAbs(boundingSphere->center().y() - sphereCenter.y()) < 0.000001f);
- QVERIFY(qAbs(boundingSphere->center().z() - sphereCenter.z()) < 0.000001f);
+
+ QVERIFY(qFuzzyIsNull(boundingSphere->center().x() - sphereCenter.x()));
+ QVERIFY(qFuzzyIsNull(boundingSphere->center().y() - sphereCenter.y()));
+ QVERIFY(qFuzzyIsNull(boundingSphere->center().z() - sphereCenter.z()));
}
void checkCustomGeometry_data()
@@ -212,10 +350,10 @@ private Q_SLOTS:
QTest::addColumn<QVector3D>("expectedCenter");
QTest::addColumn<float>("expectedRadius");
QTest::addColumn<bool>("withPrimitiveRestart");
- QTest::newRow("all") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << false;
+ QTest::newRow("all") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << false;
QTest::newRow("first only") << 3 << 0 << QVector3D(0, 1, -100) << 1.0f << false;
QTest::newRow("second only") << 3 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << false;
- QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(-0.488892f, 0.0192147f, -75.4804f) << 25.5442f << true;
+ QTest::newRow("all with primitive restart") << 0 << 0 << QVector3D(0.0f, 0.0f, -75.0f) << 25.03997f << true;
QTest::newRow("first only with primitive restart") << 4 << 0 << QVector3D(0, 1, -100) << 1.0f << true;
QTest::newRow("second only with primitive restart") << 4 << int(3 * sizeof(ushort)) << QVector3D(0, -1, -50) << 1.0f << true;
}
@@ -341,18 +479,17 @@ private Q_SLOTS:
float radius = entityBackend->localBoundingVolume()->radius();
qDebug() << radius << center;
- // truncate and compare integers only
- QVERIFY(int(radius) == int(expectedRadius));
- QVERIFY(int(center.x()) == int(expectedCenter.x()));
- QVERIFY(int(center.y()) == int(expectedCenter.y()));
- QVERIFY(int(center.z()) == int(expectedCenter.z()));
+ QCOMPARE(radius, expectedRadius);
+ QCOMPARE(center.x(), expectedCenter.x());
+ QCOMPARE(center.y(), expectedCenter.y());
+ QCOMPARE(center.z(), expectedCenter.z());
}
void checkCustomPackedGeometry()
{
int drawVertexCount = 6;
- QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f);
- float expectedRadius = 25.5442f;
+ QVector3D expectedCenter(0.0f, 0.0f, -75.0f);
+ float expectedRadius = 25.03997f;
// two triangles with different Z
QByteArray vdata;
@@ -432,11 +569,10 @@ private Q_SLOTS:
float radius = entityBackend->localBoundingVolume()->radius();
qDebug() << radius << center;
- // truncate and compare integers only
- QVERIFY(int(radius) == int(expectedRadius));
- QVERIFY(int(center.x()) == int(expectedCenter.x()));
- QVERIFY(int(center.y()) == int(expectedCenter.y()));
- QVERIFY(int(center.z()) == int(expectedCenter.z()));
+ QCOMPARE(radius, expectedRadius);
+ QCOMPARE(center.x(), expectedCenter.x());
+ QCOMPARE(center.y(), expectedCenter.y());
+ QCOMPARE(center.z(), expectedCenter.z());
}
};
diff --git a/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp
index c8d862b2e..dcd39c785 100644
--- a/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp
+++ b/tests/auto/render/proximityfiltering/tst_proximityfiltering.cpp
@@ -29,6 +29,10 @@
#include <QtTest/QTest>
#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>
+#include <Qt3DRender/qgeometry.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qbuffer.h>
#include <Qt3DRender/private/nodemanagers_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/entity_p.h>
@@ -43,6 +47,40 @@ namespace {
Qt3DCore::QEntity *buildEntityAtDistance(float distance, Qt3DCore::QEntity *parent)
{
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity(parent);
+
+ // create geometry with a valid bounding volume - a single point is sufficient
+ auto geometry = new Qt3DRender::QGeometry;
+ auto vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry);
+
+ auto positionAttribute = new Qt3DRender::QAttribute;
+ positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
+ positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ positionAttribute->setVertexSize(3);
+ positionAttribute->setByteStride(3 * sizeof(float));
+ positionAttribute->setBuffer(vertexBuffer);
+
+ QByteArray vertexBufferData;
+ vertexBufferData.resize(static_cast<int>(3 * sizeof(float)));
+
+ auto vertexArray = reinterpret_cast<float*>(vertexBufferData.data());
+
+ int i = 0;
+ vertexArray[i++] = 0.0f;
+ vertexArray[i++] = 0.0f;
+ vertexArray[i++] = 0.0f;
+
+ vertexBuffer->setData(vertexBufferData);
+ positionAttribute->setCount(1);
+
+ geometry->addAttribute(positionAttribute);
+
+ auto geometryRenderer = new Qt3DRender::QGeometryRenderer;
+ geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points);
+ geometryRenderer->setGeometry(geometry);
+
+ entity->addComponent(geometryRenderer);
+
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform(parent);
const QVector3D t = QVector3D(1.0f, 0.0f, 0.0f) * distance;