Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. adding Qt3DCore::QEntity to q3dwindow dynamic(push a button to call slots in q3dwindow) cause transform odd.
Qt 6.11 is out! See what's new in the release blog

adding Qt3DCore::QEntity to q3dwindow dynamic(push a button to call slots in q3dwindow) cause transform odd.

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 2.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fisher103
    wrote on last edited by fisher103
    #1

    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 = app

    SOURCES += main.cpp
    window3d.cpp
    widget3d.cpp

    HEADERS += window3d.h
    widget3d.h

    main.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_OBJECT

    public:

    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_OBJECT

    public:

    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()
    {

    }

    1 Reply Last reply
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by m.sue
      #2

      Hi,

      you may need to update() the Qt3DWindow explicitly.

      -Michael.

      F 1 Reply Last reply
      0
      • m.sueM m.sue

        Hi,

        you may need to update() the Qt3DWindow explicitly.

        -Michael.

        F Offline
        F Offline
        fisher103
        wrote on last edited by
        #3

        @m.sue I have tried Qt3DWindow::requestUpdate() after building sphere but it makes no diffrence. Also I call it in the timer, it keeps the same.
        Any other advices?

        1 Reply Last reply
        0
        • m.sueM Offline
          m.sueM Offline
          m.sue
          wrote on last edited by
          #4

          Hi,

          please show how you create the second sphere, the "set translation" functions and how you call it.

          -Michael.

          F 1 Reply Last reply
          0
          • m.sueM m.sue

            Hi,

            please show how you create the second sphere, the "set translation" functions and how you call it.

            -Michael.

            F Offline
            F Offline
            fisher103
            wrote on last edited by
            #5

            @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.

            1 Reply Last reply
            0
            • m.sueM Offline
              m.sueM Offline
              m.sue
              wrote on last edited by
              #6

              Hi,

              I see two difference to how I do it:

              • I do not set the root entity as parent to the mesh, material nor transform.
              • I create a new mesh for each sphere.

              Hope that helps.

              -Michael.

              F 1 Reply Last reply
              1
              • m.sueM m.sue

                Hi,

                I see two difference to how I do it:

                • I do not set the root entity as parent to the mesh, material nor transform.
                • I create a new mesh for each sphere.

                Hope that helps.

                -Michael.

                F Offline
                F Offline
                fisher103
                wrote on last edited by fisher103
                #7

                @m.sue I remove the root entity as parent to the mesh, material nor transform. it really works, thanks very much....
                but I do not know why it acts like that way.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved