Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt3D: QObjectPicker test not working as expected
Forum Updated to NodeBB v4.3 + New Features

Qt3D: QObjectPicker test not working as expected

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 1 Posters 2.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    drobole
    wrote on last edited by drobole
    #1

    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();
    }
    
    D 1 Reply Last reply
    0
    • D drobole

      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();
      }
      
      D Offline
      D Offline
      drobole
      wrote on last edited by drobole
      #2

      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();
      }
      
      
      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved