On my rootEntity I have 2 entities (parents) which are composed of multiple entities (child). I'd like to have one QObjectPicker but working only for some entities.
For the moment I have my QObjectPicker that I add to the rootEntity and that detect picking for all my entities on screen (it detect child when I click on it). But I want that some of the child become not pickable.
My first idea was to share the QObjectPicker for all the entities that require it (for all the child that need to be pickable). But a QObjectPicker is not a sharable object. Is there a way to do what I want?
-RootEntity
--ParentX
---ChildX1
---ChildX2
--ParentY
---ChildY1
---ChildY2
Edit 1 :
I tried to use the QNoPicking class in my framegraph like suggested by Florian Blume. But I can't find a way to make it work.
here is an example:
QtPicking.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtPicking.h"
#include <QApplication>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DRender/QFrameGraphNode>
#include <Qt3DRender/QClearBuffers>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/QRenderStateSet>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QDepthTest>
#include <Qt3DRender/QViewport>
#include <Qt3DRender/QPointSize>
#include <Qt3DRender/QLineWidth>
#include <Qt3DRender/QFrameGraphNode>
#include <Qt3DRender/QTechniqueFilter>
#include <Qt3DRender/QLayer>
#include <Qt3DRender/QLayerFilter>
#include <Qt3DRender/QNoPicking>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DCore/QEntity>
#include <Qt3DRender/QObjectPicker>
#include <Qt3DRender/QPickEvent>
#include <Qt3DExtras/QOrbitCameraController>
class QtPicking : public QMainWindow
{
Q_OBJECT
public:
QtPicking(QWidget *parent = Q_NULLPTR);
void loadScene(Qt3DCore::QEntity * rootEntity, Qt3DRender::QLayer * noPickingLayer);
private:
Ui::QtPickingClass ui;
};
QtPicking.cpp class
#include "QtPicking.h"
QtPicking::QtPicking(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//Qt3DWindow
Qt3DExtras::Qt3DWindow * viewer3D = new Qt3DExtras::Qt3DWindow();
Qt3DCore::QEntity * rootEntity = new Qt3DCore::QEntity();
viewer3D->setRootEntity(rootEntity);
viewer3D->setFlags(Qt::Widget);
//insert qt3dwindow inside gui
QWidget * WidgetViewer = QWidget::createWindowContainer(viewer3D, this, Qt::Widget);
this->ui.layout->addWidget(WidgetViewer);
//layer no picking
Qt3DRender::QLayer* noPickingLayer = new Qt3DRender::QLayer();
//************************** SETTING THE FRAMEGRAPH
//camera
Qt3DRender::QCamera* camera = viewer3D->camera();
camera->setPosition(QVector3D(10, 5, 5));
camera->setViewCenter(QVector3D(0, 0, 0));
camera->setParent(rootEntity);
Qt3DExtras::QOrbitCameraController* manipulator = new Qt3DExtras::QOrbitCameraController(rootEntity);
manipulator->setLinearSpeed(50.f);
manipulator->setLookSpeed(180.f);
manipulator->setCamera(camera);
//render settings
Qt3DRender::QRenderSurfaceSelector* surfaceSelector = new Qt3DRender::QRenderSurfaceSelector();
surfaceSelector->setSurface(viewer3D);
Qt3DRender::QViewport* viewport = new Qt3DRender::QViewport(surfaceSelector);
viewport->setNormalizedRect(QRectF(0, 0, 1.0, 1.0));
Qt3DRender::QCameraSelector* cameraSelector = new Qt3DRender::QCameraSelector(viewport);
cameraSelector->setCamera(camera);
Qt3DRender::QClearBuffers* clearBuffers = new Qt3DRender::QClearBuffers(cameraSelector);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
clearBuffers->setClearColor(Qt::white);
//renderstate
Qt3DRender::QRenderStateSet* renderStateSet = new Qt3DRender::QRenderStateSet(cameraSelector);
//culling => surface
Qt3DRender::QCullFace* cullFace = new Qt3DRender::QCullFace(renderStateSet);
cullFace->setMode(Qt3DRender::QCullFace::NoCulling);
renderStateSet->addRenderState(cullFace);
//taille des points
Qt3DRender::QPointSize* pointsize = new Qt3DRender::QPointSize(renderStateSet);
pointsize->setSizeMode(Qt3DRender::QPointSize::Fixed);
pointsize->setValue(2);
renderStateSet->addRenderState(pointsize);
Qt3DRender::QDepthTest* depthTest = new Qt3DRender::QDepthTest(renderStateSet);
depthTest->setDepthFunction(Qt3DRender::QDepthTest::LessOrEqual);
renderStateSet->addRenderState(depthTest);
Qt3DRender::QLayerFilter* pickingFilter = new Qt3DRender::QLayerFilter(cameraSelector);
pickingFilter->addLayer(noPickingLayer);
Qt3DRender::QNoPicking* noPicking = new Qt3DRender::QNoPicking(pickingFilter);
viewer3D->setActiveFrameGraph(surfaceSelector);
//load scene
loadScene(rootEntity, noPickingLayer);
}
/* Load a scene with 1 parent entity and 2 child
* The parent hold the picker.
* One of the entity must be pickable and the other no. => using layerfilter
*/
void QtPicking::loadScene(Qt3DCore::QEntity* rootEntity, Qt3DRender::QLayer* noPickingLayer)
{
//scene
Qt3DExtras::QPhongMaterial* material = new Qt3DExtras::QPhongMaterial(rootEntity);
material->setAmbient(Qt::black);
Qt3DCore::QEntity* parentEntity = new Qt3DCore::QEntity(rootEntity);
//first child => must be pickable
Qt3DCore::QEntity* child1 = new Qt3DCore::QEntity(parentEntity);
Qt3DExtras::QSphereMesh* child1Mesh = new Qt3DExtras::QSphereMesh;
child1Mesh->setRadius(1);
Qt3DCore::QTransform* child1Transform = new Qt3DCore::QTransform();
child1Transform->setTranslation(QVector3D(2, 2, 2));
child1->addComponent(child1Mesh);
child1->addComponent(child1Transform);
child1->addComponent(material);
//second child => must NOT be pickable
Qt3DCore::QEntity* child2 = new Qt3DCore::QEntity(parentEntity);
Qt3DExtras::QSphereMesh* child2Mesh = new Qt3DExtras::QSphereMesh;
child2Mesh->setRadius(2);
child2->addComponent(child2Mesh);
child2->addComponent(material);
child2->addComponent(noPickingLayer);
Qt3DRender::QObjectPicker* picker = new Qt3DRender::QObjectPicker();
picker->setEnabled(true);
parentEntity->addComponent(picker);
connect(picker, &Qt3DRender::QObjectPicker::clicked, this, [this](Qt3DRender::QPickEvent* event) {
qDebug() << "clicked";
});
}
Even without the renderStateSet set as QLayerFilter's parent and with different parent I can't make it work... either everything is pickable, either there is only the pickable entity that are displayed (or the opposite)
I even tried with 2 pickerLayer, but I can't get it work
Any idea?