问题描述
在我的rootEntity上,我有2个实体(父级),由多个实体(子级)组成。 我想拥有一个QObjectPicker,但仅适用于某些实体。
目前,我有我的QObjectPicker,我将其添加到rootEntity并检测屏幕上所有实体的拾取情况(当我单击它时,它会检测子对象)。但是我希望其中的一些孩子变得不能被拣选。
我的第一个想法是为所有需要它的实体(对于所有需要选择的子对象)共享QObjectPicker。但是QObjectPicker不是可共享的对象。 有什么方法可以做我想要的吗?
-RootEntity
--ParentX
--- ChildX1
--- ChildX2
--ParentY
--- ChildY1
--- ChildY2
编辑1:
我尝试像Florian Blume建议的那样在我的框架图中使用Qnopicking类。 但是我找不到一种使它起作用的方法
这是一个示例:
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类
#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));
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,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](Qt3DRender::QPickEvent* event) {
qDebug() << "clicked";
});
}
即使没有将renderStateSet设置为QLayerFilter的父级,并且将父级与其他父级设置为不同,我也无法使其正常工作... 要么一切都是可拣选的,要么只显示了可拣选实体(或相反)
我什至尝试了2个pickerLayer,但无法正常工作
有什么主意吗?
解决方法
您可以在框架图中使用QNoPicking
类,并在要阻止QObjectPicker
选取的实体上添加图层过滤器和图层。