Qt3D: QObjectPicker test not working as expected
-
Hi,
I'm trying to make picking work with a simple C++ widget application, using QtCreator 4.2.1 and Qt 5.8.0
The example creates two spheres, a green one at 0,0,0 and a red one at -20, 0, 0
No matter where I click in the 3D space, the green one is hit by the picker ray, no matter what.
However, if I rotate the scene so that the red sphere is exactly in front of the green sphere, the ray hits the red one. Again, no matter what or where I click.
Basically, it seems that the ray always goes from the camera to origo (0,0,0) regardless of where I click with the mouse.
Any tips out there on what I'm forgetting, or doing wrong?
Here is the .cpp file of the example:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <Qt3DCore/QEntity> #include <Qt3DRender/QCamera> #include <Qt3DRender/QCameraLens> #include <Qt3DRender/QRenderSettings> #include <Qt3DRender/QObjectPicker> #include <Qt3DExtras/QForwardRenderer> #include <Qt3DExtras/Qt3DWindow> #include <Qt3DExtras/QOrbitCameraController> #include <Qt3DExtras/QSphereMesh> #include <Qt3DCore/QTransform> #include <Qt3DExtras/QPhongMaterial> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); Qt3DExtras::Qt3DWindow *mView = new Qt3DExtras::Qt3DWindow(); QWidget *mContainerScene = QWidget::createWindowContainer(mView, this); ui->layoutScene->addWidget(mContainerScene); Qt3DRender::QCamera *mCamera = mView->camera(); mCamera->setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection); //mCamera->setAspectRatio(mView->width() / mView->height()); mCamera->setAspectRatio(16.0f / 9.0f); mCamera->setFieldOfView(45.0f); mCamera->setUpVector(QVector3D(0.0f, 1.0f, 0.0f)); mCamera->setPosition(QVector3D(0.0f, 20.0f, 80.0f)); mCamera->setViewCenter(QVector3D(0.0f, 0.0f, 0.0f)); mCamera->setNearPlane(0.01f); mCamera->setFarPlane(100000.0f); mView->defaultFrameGraph()->setClearColor(QColor(0, 0, 0)); Qt3DRender::QRenderSettings *mRenderSettings = new Qt3DRender::QRenderSettings(); mRenderSettings->pickingSettings()->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking); mRenderSettings->pickingSettings()->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick); mRenderSettings->setActiveFrameGraph(mView->defaultFrameGraph()); Qt3DCore::QEntity *mSceneEntity = new Qt3DCore::QEntity(); mSceneEntity->addComponent(mRenderSettings); mSceneEntity->setObjectName(QStringLiteral("scene entity")); Qt3DExtras::QOrbitCameraController *mCameraController = new Qt3DExtras::QOrbitCameraController(mSceneEntity); mCameraController->setLinearSpeed(50.0f); mCameraController->setLookSpeed(180.0f); mCameraController->setCamera(mCamera); // Create entity 1 Qt3DCore::QEntity *entity1 = new Qt3DCore::QEntity(mSceneEntity); entity1->setObjectName("entity 1"); Qt3DExtras::QSphereMesh *mMesh1 = new Qt3DExtras::QSphereMesh(entity1); mMesh1->setRadius(1.0f); entity1->addComponent(mMesh1); Qt3DCore::QTransform *mTransform1 = new Qt3DCore::QTransform(entity1); mTransform1->setTranslation(QVector3D(0, 0, 0)); mTransform1->setScale(1); mTransform1->setScale3D(QVector3D(1, 1, 1)); entity1->addComponent(mTransform1); Qt3DExtras::QPhongMaterial *mMaterial1 = new Qt3DExtras::QPhongMaterial(entity1); QColor color(0, 255, 0); mMaterial1->setDiffuse(color); mMaterial1->setSpecular(color); mMaterial1->setAmbient(color); mMaterial1->setShininess(5.0f); entity1->addComponent(mMaterial1); Qt3DRender::QObjectPicker *picker1 = new Qt3DRender::QObjectPicker(entity1); picker1->setHoverEnabled(false); picker1->setEnabled(true); QObject::connect(picker1, &Qt3DRender::QObjectPicker::pressed, this, &MainWindow::onPicked); entity1->addComponent(picker1); // Create entity 2 Qt3DCore::QEntity *entity2 = new Qt3DCore::QEntity(mSceneEntity); entity2->setObjectName("entity 2"); Qt3DExtras::QSphereMesh *mMesh2 = new Qt3DExtras::QSphereMesh(entity2); mMesh2->setRadius(1.0f); entity2->addComponent(mMesh2); Qt3DCore::QTransform *mTransform2 = new Qt3DCore::QTransform(entity2); mTransform2->setTranslation(QVector3D(-20, 0, 0)); mTransform2->setScale(1); mTransform2->setScale3D(QVector3D(1, 1, 1)); entity2->addComponent(mTransform2); Qt3DExtras::QPhongMaterial *mMaterial2 = new Qt3DExtras::QPhongMaterial(entity2); QColor color2(255, 0, 0); mMaterial2->setDiffuse(color2); mMaterial2->setSpecular(color2); mMaterial2->setAmbient(color2); mMaterial2->setShininess(5.0f); entity2->addComponent(mMaterial2); Qt3DRender::QObjectPicker *picker2 = new Qt3DRender::QObjectPicker(entity2); picker2->setHoverEnabled(false); picker2->setEnabled(true); QObject::connect(picker2, &Qt3DRender::QObjectPicker::pressed, this, &MainWindow::onPicked); entity2->addComponent(picker2); mView->setRootEntity(mSceneEntity); mView->show(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onPicked(Qt3DRender::QPickEvent *evt) { Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity*>(sender()->parent()); qDebug() << "Picked " << entity->objectName(); }
-
Not sure what is going on here but not creating a RenderSetting and not setting the camera aspect ratio and FOW solved the issue.
By creating a custom RenderSettings I may have ended up with a orthogonal projection or something.Here is a working example:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <Qt3DCore/QEntity> #include <Qt3DRender/QCamera> #include <Qt3DRender/QCameraLens> #include <Qt3DRender/QObjectPicker> #include <Qt3DExtras/QForwardRenderer> #include <Qt3DExtras/Qt3DWindow> #include <Qt3DExtras/QOrbitCameraController> #include <Qt3DExtras/QSphereMesh> #include <Qt3DCore/QTransform> #include <Qt3DExtras/QPhongMaterial> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow(); QWidget *containerScene = QWidget::createWindowContainer(view, this); ui->layoutScene->addWidget(containerScene); Qt3DRender::QCamera *camera = view->camera(); camera->setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection); camera->setUpVector(QVector3D(0.0f, 1.0f, 0.0f)); camera->setPosition(QVector3D(0.0f, 20.0f, 80.0f)); camera->setViewCenter(QVector3D(0.0f, 0.0f, 0.0f)); view->defaultFrameGraph()->setClearColor(QColor(0, 0, 0)); Qt3DCore::QEntity *sceneEntity = new Qt3DCore::QEntity(); Qt3DExtras::QOrbitCameraController *cameraController = new Qt3DExtras::QOrbitCameraController(sceneEntity); cameraController->setLinearSpeed(50.0f); cameraController->setLookSpeed(180.0f); cameraController->setCamera(camera); // Create entity 1 Qt3DCore::QEntity *entity1 = new Qt3DCore::QEntity(sceneEntity); entity1->setObjectName("entity 1"); Qt3DExtras::QSphereMesh *mesh1 = new Qt3DExtras::QSphereMesh(entity1); mesh1->setRadius(1.0f); entity1->addComponent(mesh1); Qt3DCore::QTransform *transform1 = new Qt3DCore::QTransform(entity1); transform1->setTranslation(QVector3D(0, 0, 0)); transform1->setScale(1); transform1->setScale3D(QVector3D(1, 1, 1)); entity1->addComponent(transform1); Qt3DExtras::QPhongMaterial *material1 = new Qt3DExtras::QPhongMaterial(entity1); QColor color(0, 255, 0); material1->setDiffuse(color); material1->setSpecular(color); material1->setAmbient(color); material1->setShininess(5.0f); entity1->addComponent(material1); Qt3DRender::QObjectPicker *picker1 = new Qt3DRender::QObjectPicker(entity1); picker1->setHoverEnabled(false); picker1->setEnabled(true); QObject::connect(picker1, &Qt3DRender::QObjectPicker::pressed, this, &MainWindow::onPicked); entity1->addComponent(picker1); // Create entity 2 Qt3DCore::QEntity *entity2 = new Qt3DCore::QEntity(sceneEntity); entity2->setObjectName("entity 2"); Qt3DExtras::QSphereMesh *mesh2 = new Qt3DExtras::QSphereMesh(entity2); mesh2->setRadius(1.0f); entity2->addComponent(mesh2); Qt3DCore::QTransform *transform2 = new Qt3DCore::QTransform(entity2); transform2->setTranslation(QVector3D(-20, 0, 0)); transform2->setScale(1); transform2->setScale3D(QVector3D(1, 1, 1)); entity2->addComponent(transform2); Qt3DExtras::QPhongMaterial *material2 = new Qt3DExtras::QPhongMaterial(entity2); QColor color2(255, 0, 0); material2->setDiffuse(color2); material2->setSpecular(color2); material2->setAmbient(color2); material2->setShininess(5.0f); entity2->addComponent(material2); Qt3DRender::QObjectPicker *picker2 = new Qt3DRender::QObjectPicker(entity2); picker2->setHoverEnabled(false); picker2->setEnabled(true); QObject::connect(picker2, &Qt3DRender::QObjectPicker::pressed, this, &MainWindow::onPicked); entity2->addComponent(picker2); view->setRootEntity(sceneEntity); view->show(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onPicked(Qt3DRender::QPickEvent *evt) { Qt3DCore::QEntity *entity = qobject_cast<Qt3DCore::QEntity*>(sender()->parent()); qDebug() << "Picked " << entity->objectName(); }