【发布时间】:2021-02-21 09:56:53
【问题描述】:
在我的 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, 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";
});
}
即使没有将 renderStateSet 设置为 QLayerFilter 的父级和不同的父级,我也无法使其工作... 要么一切都是可挑选的,要么只显示可挑选的实体(或相反)
我什至尝试了 2 个pickerLayer,但我无法让它工作
有什么想法吗?
【问题讨论】:
-
很难从你的例子中看出你做错了什么。请提供minimal reproducible example。