【问题标题】:Qt3D - Disable certain entity to be pickable (with QObjectPicker set to rootEntity)Qt3D - 禁用某些实体可拾取(QObjectPicker 设置为 rootEntity)
【发布时间】: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,但我无法让它工作

有什么想法吗?

【问题讨论】:

标签: c++ qt opengl qt3d


【解决方案1】:

您可以在框架图中使用QNoPicking 类以及图层过滤器和添加到要防止QObjectPicker 拾取的实体的图层。

【讨论】:

  • 我知道应该是这样的:Qt3DRender::QLayerFilter * PickFilter = new Qt3DRender::QLayerFilter(cameraSelector); PickingFilter->addLayer(this->pickingLayer); Qt3DRender::QNoPicking * noPicking = new Qt3DRender::QNoPicking(pickingFilter);
  • 是的,然后您必须将 PickingFilter 层添加到您不想选择的对象中。 QNoPicking 节点我猜应该是一个叶节点,因为您不希望拾取和未拾取的对象使用不同的框架图分支。
  • 嘿!我只是编辑我的帖子,因为我无法让它工作。如果你有时间:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多