2

I have a simple Qt3D example (attached below) and I'd like to be able to rotate the camera around the object - right now the object rotates around the camera. I've found some suggestions for other frameworks and am wondering what the best way is to do this in Qt3D?

main.cpp

#include <QApplication>
#include <QWidget>

#include "Viewer3d.h"


int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    auto* v3d = new Viewer3d(nullptr);

    v3d->setMinimumSize(800 * 2, 600 * 2);
    v3d->show();

    return app.exec();
}

Viewer3d.h

#pragma once

#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>

#include <Qt3DRender/qrenderaspect.h>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QMaterial>
#include <Qt3DRender/QPointLight>

#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QFirstPersonCameraController>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <QtWidgets/QWidget>
#include <QScreen>

class Viewer3d: public QWidget {
public:
    explicit Viewer3d(QWidget* parent= nullptr);

private:
    Qt3DCore::QEntity* m_rootEntity;
    Qt3DExtras::Qt3DWindow *m_view;

};

Viewer3d.cpp

#include <QHBoxLayout>
#include "Viewer3d.h"

Viewer3d::Viewer3d(QWidget *parent): QWidget(parent) {
    m_view = new Qt3DExtras::Qt3DWindow();
    m_view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));

    m_rootEntity = new Qt3DCore::QEntity;

    auto* torus = new Qt3DCore::QEntity(m_rootEntity);

    auto* mesh = new Qt3DExtras::QTorusMesh;
    mesh->setRadius(5);
    mesh->setMinorRadius(1);
    mesh->setRings(100);
    mesh->setSlices(20);

    auto* cube = new Qt3DCore::QEntity(m_rootEntity);

    auto cubeMesh = new Qt3DExtras::QCuboidMesh;
    cubeMesh->setXExtent(4);
    cubeMesh->setYExtent(4);
    cubeMesh->setZExtent(4);

    auto* transform = new Qt3DCore::QTransform;
    transform->setTranslation(QVector3D(0, 0, 0));
//    transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1,0,0), 45.f ));

    Qt3DRender::QMaterial* material = new Qt3DExtras::QPhongMaterial(m_rootEntity);

    torus->addComponent(mesh);
    torus->addComponent(transform);
    torus->addComponent(material);

    cube->addComponent(cubeMesh);
    cube->addComponent(transform);
    cube->addComponent(material);



    // Camera
    Qt3DRender::QCamera *cameraEntity = m_view->camera();
//    cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    cameraEntity->setPosition(QVector3D(0, 0, 40.0f));
//    cameraEntity->setViewCenter(QVector3D(0, 0, 0));

//    cameraEntity->setPosition(QVector3D(0, 0, 500.0f));
//    cameraEntity->setUpVector(QVector3D(0, 1, 0));
//    cameraEntity->setViewCenter(QVector3D(0, 0, 0));
//    cameraEntity->transform()->setScale(1.f);


    // manipulator
    auto* manipulator = new Qt3DExtras::QOrbitCameraController (m_rootEntity);
    manipulator->setLinearSpeed(50.f);
    manipulator->setLookSpeed(180.f);
    manipulator->setCamera(cameraEntity);

    // light
    auto *lightEntity = new Qt3DCore::QEntity(m_rootEntity);
    auto *light = new Qt3DRender::QPointLight(lightEntity);
    light->setColor("white");
    light->setIntensity(1);
    lightEntity->addComponent(light);
    auto *lightTransform = new Qt3DCore::QTransform(lightEntity);
    lightTransform->setTranslation(cameraEntity->position());
    lightEntity->addComponent(lightTransform);

    // Set root object of the scene
    m_view->setRootEntity(m_rootEntity);

    QWidget *container = QWidget::createWindowContainer(m_view);
    QSize screenSize = m_view->screen()->size();
    container->setMinimumSize(QSize(200, 100));
    container->setMaximumSize(screenSize);

    auto *hLayout = new QHBoxLayout(this);
    hLayout->addWidget(container, 1);

    setLayout(hLayout);

}

Is there a straightforward way to this in Qt3D?

user31208
  • 1,448
  • 1
  • 18
  • 22
  • What more straightforward way can you possibly hope for than a built-in class `QOrbitCameraController` that you can initialize in 4 lines of code? – meowgoesthedog Feb 04 '18 at 12:21
  • The issue is not the camera controller - I'm wondering how to modify it so it rotates around the object, not the other way around. – user31208 Feb 04 '18 at 12:57
  • That's how the `QOrbitCameraController` works. It rotates the camera around the object. – vre Feb 06 '18 at 09:59

2 Answers2

0

if you know how to rotate it on the spot, and move it. basically try reversing the order you're doing the translations. if you rotate something, everything rotates around the mathematical origin (0,0). so if you rotate it first (so it's rotated), then you shift it into the distance, it'll be rotating in the distance. or by other perspective, you'll be asif you're orbiting it.

Puddle
  • 2,993
  • 1
  • 19
  • 32
0

https://github.com/sonichy/HTYCAD

QVector3D vector3D = camera->position();
qreal r = qSqrt(vector3D.x() * vector3D.x() + vector3D.z() * vector3D.z());
for(qreal a=0; a<2 * M_PI; a+= 0.01){
    qreal z = r * qSin(a);
    qreal x = r * qCos(a);
    vector3D.setX(x);
    vector3D.setZ(z);
    camera->setPosition(vector3D);
    camera->setUpVector(QVector3D(0, 1, 0));
    ui->statusBar->showMessage("a = " + QString::number(a) + ", Camera Position (" + QString::number(camera->position().x()) + ", " + QString::number(camera->position().y()) + ", " + QString::number(camera->position().z()) + ")");
    QEventLoop eventloop;
    QTimer::singleShot(100, &eventloop, SLOT(quit()));
    eventloop.exec();
}
sonichy
  • 1,370
  • 2
  • 14
  • 17