adding Qt3DCore::QEntity to q3dwindow dynamic(push a button to call slots in q3dwindow) cause transform odd.
-
we create 3d object like this in qt5.8-windows:
//build a sphere
m_sphereMesh = new Qt3DExtras::QSphereMesh(m_pRootEntity);
m_mainSphereTransfrom = new Qt3DCore::QTransform(m_pRootEntity);
m_mainSphereMaterial = new Qt3DExtras::QPhongMaterial(m_pRootEntity);//add component to sphere
Qt3DCore::QEntity *mainEntity = new Qt3DCore::QEntity(m_pRootEntity);
mainEntity->addComponent(m_sphereMesh);
mainEntity->addComponent(m_mainSphereMaterial);
mainEntity->addComponent(m_mainSphereTransfrom);everything goes well when we do all these(build all spheres) in initial time. but when we add a button to add another sphere during running time, this new build sphere act unnormal for move command like (m_newSphereTransfrom->setTranslation(m_posNewPos);)
but the sphere display normal like pick, set color, or scale. only cannot move or rotate as initial-time build spheres.
===================================
follow are all the source code, when your press the closer button, you will find that new sphere would not moved, but the position return by transform is changed.
===================================test3d.pro
QT += core gui 3dcore 3drender 3dextras
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test3d
TEMPLATE = appSOURCES += main.cpp
window3d.cpp
widget3d.cppHEADERS += window3d.h
widget3d.hmain.cpp
#include <QApplication>
#include "widget3d.h"int main(int argc, char *argv[])
{QApplication a(argc, argv); Widget3D mainWidget; mainWidget.show(); return a.exec();
}
window3d.h
#ifndef WINDOW3D_H
#define WINDOW3D_H#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DCore>
#include <Qt3DExtras/qphongmaterial.h>
#include <QPickEvent>
#include <QmouseEvent>
#include <Qt3DExtras/qcylindermesh.h>
#include <Qt3DExtras/qspheremesh.h>class Window3D : public Qt3DExtras::Qt3DWindow
{
Q_OBJECTpublic:
Window3D(QObject *parent = 0); ~Window3D(); void install3dEnvironment(); void createSphere();
public slots:
void createNewSphere(); void beCloser();
protected:
void addDirectLight(const QVector3D & pos, const QVector3D & dir, float intensity);
private:
Qt3DCore::QEntity *m_pRootEntity; Qt3DCore::QEntity * m_sphere; Qt3DExtras::QSphereMesh *m_mesh; Qt3DExtras::QPhongMaterial *m_material; Qt3DCore::QTransform *m_transfrom; Qt3DCore::QEntity * m_newSphere; Qt3DExtras::QSphereMesh *m_newMesh; Qt3DExtras::QPhongMaterial *m_newMaterial; Qt3DCore::QTransform *m_newTransfrom;
};
#endif // WINDOW3D_H
window3d.cpp
#include "window3d.h"
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <QOrbitCameraController>Window3D::Window3D(QObject *parent):
m_pRootEntity(0),
m_sphere(0),
m_mesh(0),
m_material(0),
m_transfrom(0),
m_newSphere(0),
m_newMesh(0),
m_newMaterial(0),
m_newTransfrom(0)
{m_pRootEntity = new Qt3DCore::QEntity(); setRootEntity(m_pRootEntity); install3dEnvironment(); createSphere();
}
Window3D::~Window3D()
{}
void Window3D::addDirectLight(const QVector3D & pos, const QVector3D & dir, float intensity)
{Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(m_pRootEntity); Qt3DRender::QDirectionalLight *light = new Qt3DRender::QDirectionalLight(m_pRootEntity); light->setColor("white"); light->setIntensity(intensity); light->setWorldDirection(dir); Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(m_pRootEntity); lightTransform->setTranslation(pos); lightEntity->addComponent(light); lightEntity->addComponent(lightTransform);
}
void Window3D::install3dEnvironment()
{Qt3DRender::QCamera *cameraEntity = camera(); cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 100.0f); cameraEntity->setPosition(QVector3D(0, 0, 20)); cameraEntity->setUpVector(QVector3D(0, 1, 0)); cameraEntity->setViewCenter(QVector3D(0, 0, 0)); addDirectLight(QVector3D(0, 0, 20), QVector3D(0, 0, -20), 1); Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(m_pRootEntity); camController->setCamera(cameraEntity);
}
void Window3D::createSphere()
{m_mesh = new Qt3DExtras::QSphereMesh(m_pRootEntity); m_mesh->setRings(20); m_mesh->setSlices(50); m_mesh->setRadius(1); m_transfrom = new Qt3DCore::QTransform(m_pRootEntity); m_transfrom->setTranslation(QVector3D(-4,0,0));//set position m_material = new Qt3DExtras::QPhongMaterial(m_pRootEntity); m_material->setDiffuse("yellow"); m_sphere = new Qt3DCore::QEntity(m_pRootEntity); m_sphere->addComponent(m_mesh); m_sphere->addComponent(m_transfrom); m_sphere->addComponent(m_material);
}
void Window3D::createNewSphere()
{if (m_newSphere) return; m_newMesh = new Qt3DExtras::QSphereMesh(m_pRootEntity); m_newMesh->setRings(20); m_newMesh->setSlices(50); m_newMesh->setRadius(2); m_newTransfrom = new Qt3DCore::QTransform(m_pRootEntity); m_newTransfrom->setTranslation(QVector3D(4,0,0));//set position m_newMaterial = new Qt3DExtras::QPhongMaterial(m_pRootEntity); m_newMaterial->setDiffuse("green"); m_newSphere = new Qt3DCore::QEntity(m_pRootEntity); m_newSphere->addComponent(m_newMesh); m_newSphere->addComponent(m_newTransfrom); m_newSphere->addComponent(m_newMaterial);
}
void Window3D::beCloser()
{if (m_newSphere && m_sphere) { m_transfrom->setTranslation(m_transfrom->translation()+QVector3D(0.1,0,0)); m_newTransfrom->setTranslation(m_newTransfrom->translation() + QVector3D(-0.2, 0, 0)); qDebug() << "new position:" << m_transfrom->translation() << m_newTransfrom->translation(); }
}
widget3d.h
#ifndef WIDGET3D_H
#define WIDGET3D_H#include "window3d.h"
#include <QWidget>class Widget3D : public QWidget
{
Q_OBJECTpublic:
Widget3D(QObject *parent = 0); ~Widget3D();
private:
Window3D * m_wind3d;
};
#endif // WIDGET3D_H
widget3d.cpp
#include "widget3d.h"
#include <QPushButton>
#include <QHBoxLayout>Widget3D::Widget3D(QObject *parent)
{m_wind3d = new Window3D(); QWidget *view3d = QWidget::createWindowContainer(m_wind3d,this); QSize screenSize = m_wind3d->screen()->size(); view3d->setMinimumSize(QSize(800, 500)); view3d->setMaximumSize(screenSize); QHBoxLayout *hLayout = new QHBoxLayout(this); QVBoxLayout *vLayout = new QVBoxLayout(this); hLayout->addWidget(view3d); hLayout->addLayout(vLayout); QPushButton *addNewSphere = new QPushButton(this); addNewSphere->setText(tr("New Sphere")); connect(addNewSphere, SIGNAL(clicked()), m_wind3d, SLOT(createNewSphere())); vLayout->addWidget(addNewSphere); QPushButton *closerSphere = new QPushButton(this); closerSphere->setText(tr("Be Closer")); connect(closerSphere, SIGNAL(clicked()), m_wind3d, SLOT(beCloser())); vLayout->addWidget(closerSphere); this->setLayout(hLayout);
}
Widget3D::~Widget3D()
{}
-
@m.sue the creation are the same. like this:
Qt3DCore::QTransform *localTransform = new Qt3DCore::QTransform(m_pRootEntity);
localTransform->setTranslation(pt3d);
m_vecSphereTransform.append(localTransform);Qt3DExtras::QPhongMaterial *localMaterial = new Qt3DExtras::QPhongMaterial(m_pRootEntity);
localMaterial->setDiffuse(m_colorSphere);
m_vecSphereMaterial.append(localMaterial);Qt3DCore::QEntity *localEntity = new Qt3DCore::QEntity(m_pRootEntity);
localEntity->addComponent(m_sphereMesh);
localEntity->addComponent(localMaterial);
localEntity->addComponent(localTransform);
m_vecSpheres.push_back(localEntity);we save the pointer to QTransform into a vector and operate the position with the pointer in a timer.