Как исключить пустой QEntity из вычисления ограничивающего объема
Моя компания использует Qt3D для отображения своих моделей САПР. Wee пробовал использовать функциюQCamera::viewEntity(Qt3DCore::QEntity *entity)
для вычисления ограничивающей сферы данного объекта, а также для размещения объекта на экране.
Теперь мы столкнулись с неразрешимой проблемой в случае пустого QEntity
узлы. Я назову узел пустым, если он все-таки не содержит ни одной вершины / точки. В этом случае я ожидал, что им следует пренебречь при вычислении ограничивающего объема. Вместо этого кажется, что он будет рассматриваться, так как он имеет ограничивающую сферу с центром (0.,0.,0.) и радиусом 0.
Следующий код иллюстрирует проблему:
main.cpp
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QFrame>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <QPushButton>
Qt3DCore::QEntity* createSphereMesh()
{
auto sphereMat = new Qt3DExtras::QDiffuseSpecularMaterial;
sphereMat->setDiffuse(QColor(Qt::blue));
auto mesh = new Qt3DExtras::QSphereMesh();
mesh->setRadius(0.5);
auto meshEntity = new Qt3DCore::QEntity;
meshEntity->addComponent(mesh);
meshEntity->addComponent(sphereMat);
return meshEntity;
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
auto view = new Qt3DExtras::Qt3DWindow();
view->defaultFrameGraph()->setClearColor(QColor(127, 127, 127));
auto settings = view->renderSettings();
settings->setActiveFrameGraph(view->activeFrameGraph());
auto rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
auto sphere1 = createSphereMesh();
sphere1->setParent(rootEntity);
auto trafo1 = new Qt3DCore::QTransform;
trafo1->setTranslation(QVector3D(20, 10, 0));
sphere1->addComponent(trafo1);
auto sphere2 = createSphereMesh();
sphere2->setParent(rootEntity);
auto trafo2 = new Qt3DCore::QTransform;
trafo2->setTranslation(QVector3D(20, -10, 0));
sphere2->addComponent(trafo2);
QObject::connect(view->camera()->lens(), &Qt3DRender::QCameraLens::viewSphere, [&](const QVector3D& center, float radius) {
qDebug() << "Bounding Sphere:" << center << radius;
auto boundingSphereEntity = new Qt3DCore::QEntity;
auto sphereMat = new Qt3DExtras::QDiffuseSpecularMaterial;
sphereMat->setAlphaBlendingEnabled(true);
sphereMat->setDiffuse(QColor(255,255,255,80));
auto mesh = new Qt3DExtras::QSphereMesh();
mesh->setRadius(radius);
boundingSphereEntity->addComponent(sphereMat);
boundingSphereEntity->addComponent(mesh);
auto trafoAll = new Qt3DCore::QTransform;
trafoAll->setTranslation(center);
boundingSphereEntity->addComponent(trafoAll);
boundingSphereEntity->addComponent(mesh);
boundingSphereEntity->addComponent(sphereMat);
boundingSphereEntity->setParent(rootEntity);
});
auto container = QWidget::createWindowContainer(view);
auto viewAllBtn = new QPushButton("View All");
QObject::connect(viewAllBtn, &QPushButton::clicked, [&]() {
view->camera()->viewAll();
});
QFrame frame;
frame.setFixedSize(500, 500);
frame.setLayout(new QVBoxLayout);
frame.layout()->addWidget(container);
frame.layout()->addWidget(viewAllBtn);
frame.show();
return a.exec();
}
У меня есть две синие сферы с радиусом 0,5, находящиеся на расстоянии 20 друг от друга. Я ожидаю ограничивающую сферу с центром (20,0,0) и радиусом (10,5).
Вместо этого программа печатает:
Bounding Sphere: QVector3D(12.1432, 2.14455, -1.32699e-08) 14.9644
Кажется, что значение 2,14455 действительно пришло из ниоткуда, и что моя сфера добавленного ограничивающего объема несколько непредсказуема.
Если заменю перевод QVector3D(20, 10, 0)
по QVector3D(0,10,0)
результат будет таким, как ожидалось.
Как я могу исключить корневой объект из вычисления ограничивающего объема?