У меня есть Scene3D
, где я динамически добавляю сущность, которая имеет ObjectPicker
, через слот этого класса помощника 'Scene3DViewHelper::addCuboid()
:
scene3dviewhelper.h:
#ifndef SCENE3DVIEWHELPER_H
#define SCENE3DVIEWHELPER_H
#include <Qt3DCore/QEntity>
class Scene3DViewHelper : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(Qt3DCore::QEntity * rootEntity READ rootEntity WRITE setRootEntity NOTIFY rootEntityChanged)
explicit Scene3DViewHelper(QObject *parent = nullptr);
Qt3DCore::QEntity * rootEntity() const;
public slots:
void setRootEntity(Qt3DCore::QEntity *rootEntity);
void addCuboid();
signals:
void rootEntityChanged(Qt3DCore::QEntity *rootEntity);
private:
Qt3DCore::QEntity *rootEntity_;
};
#endif // SCENE3DVIEWHELPER_H
scene3dviewhelper. cpp:
#include "scene3dviewhelper.h"
#include <Qt3DCore>
#include <Qt3DRender>
#include <Qt3DExtras>
Scene3DViewHelper::Scene3DViewHelper(QObject *parent) : QObject(parent) {}
Qt3DCore::QEntity * Scene3DViewHelper::rootEntity() const { return rootEntity_; }
void Scene3DViewHelper::setRootEntity(Qt3DCore::QEntity *rootEntity)
{
auto old = rootEntity_;
rootEntity_ = rootEntity;
if(rootEntity_ != old) emit rootEntityChanged(rootEntity);
}
void Scene3DViewHelper::addCuboid()
{
if(!rootEntity_) return;
auto cuboidEntity = new Qt3DCore::QEntity(rootEntity_);
auto mat = new Qt3DExtras::QPhongMaterial(cuboidEntity);
mat->setDiffuse(QColor(217, 217, 255));
auto t = new Qt3DCore::QTransform(cuboidEntity);
auto mesh = new Qt3DExtras::QCuboidMesh(cuboidEntity);
auto picker = new Qt3DRender::QObjectPicker(cuboidEntity);
connect(picker, &Qt3DRender::QObjectPicker::clicked, [=] {
qDebug() << "clicked entity" << cuboidEntity;
});
mesh->setXExtent(1);
mesh->setYExtent(1);
mesh->setZExtent(1);
cuboidEntity->addComponent(mat);
cuboidEntity->addComponent(t);
cuboidEntity->addComponent(mesh);
cuboidEntity->addComponent(picker);
}
Scene3DView.qml:
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.14
import Qt3D.Input 2.0
import Qt3D.Logic 2.0
import Qt3D.Extras 2.0
import Qt3DUtils 1.0
Scene3D {
id: scene3d
aspects: ["render", "logic", "input"]
hoverEnabled: true // needed for ObjectPickers to handle hover events
property alias helper: helper
data: Scene3DViewHelper {
id: helper
rootEntity: rootEntity
}
entity: Entity {
id: rootEntity
components: [
RenderSettings {
ForwardRenderer {
id: forwardRenderer
camera: mainCamera
}
pickingSettings.pickMethod: PickingSettings.TrianglePicking
pickingSettings.pickResultMode: PickingSettings.AllPicks
pickingSettings.faceOrientationPickingMode: PickingSettings.FrontAndBackFace
},
InputSettings {}
]
Camera {
id: mainCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d(0.0, 0.0, -4.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
viewCenter: Qt.vector3d(0.0, 0.5, 0.0)
}
/*Entity {
id: cuboid0
components: [
CuboidMesh {
xExtent: 1
yExtent: 1
zExtent: 1
},
Transform {
translation.x: -1.5
},
PhongMaterial {
diffuse: Qt.rgba(0.85, 0.85, 1, 1)
},
ObjectPicker {
onClicked: console.log("clicked entity", cuboid0)
}
]
}*/
}
}
main.qml:
import QtQuick.Window 2.13 as QtQuick
ApplicationWindow {
id: mainWindow
visible: true
width: 1000
height: 700
MainMenu {
onAddCuboid: scene3d.helper.addCuboid()
}
Scene3DView {
id: scene3d
anchors.fill: parent
}
}
main. cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
#include "scene3dviewhelper.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
qmlRegisterType<Scene3DViewHelper>("Qt3DUtils", 1, 0, "Scene3DViewHelper");
const QUrl mainUrl(QStringLiteral("qrc:/main.qml"));
QQmlApplicationEngine engine;
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [&](QObject *obj, const QUrl &objUrl) {
if(!obj && mainUrl == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(mainUrl);
return app.exec();
}
Проблема в том, что ObjectPicker
не работает: я должен видеть сообщение "clicked entity Qt3DCore :: QEntity (0x7fa19f005300)" на консоли, когда я нажимаю на кубоид, но я не вижу его.
Если я раскомментирую сущность cuboid0
, тогда выбор будет работать как для сущности cuboid0
, так и для динамически создаваемого кубоида:
qml: clicked entity Qt3DCore :: Quick :: Quick3DEntity (0x7fa0d7c025e0)
щелкнувшая сущность Qt3DCore :: QEntity (0x7fa0d6527f10)
Что делает создание сущности в QML, чего я не делаю в void Scene3DViewHelper::addCuboid()