Qt3D rotate camera around mesh

Viewed 4395

I've recently started learning Qt/QML/C++ and trying to build a very basic 3D scene to rotate the camera around a mesh object.

I'm finding it very difficult to follow the examples and I'm finding the documentation doesn't provide any useful instructions. There doesn't seem to be many tutorials out there either, perhaps I'm looking in the wrong places.

main.cpp

#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>

#include <QGuiApplication>
#include <QtQml>

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);
    Qt3DExtras::Quick::Qt3DQuickWindow view;

    // Expose the window as a context property so we can set the aspect ratio
    view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
    view.setSource(QUrl("qrc:/main.qml"));
    view.setWidth(800);
    view.setHeight(600);
    view.show();

    return app.exec();
}

main.qml

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Entity {
    id: sceneRoot

    Camera {
        id: camera
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 25
        aspectRatio: _window.width / _window.height
        nearPlane : 0.1
        farPlane : 1000.0
        position: Qt.vector3d( 0, 0.0, 20.0 )
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
    }

    OrbitCameraController {
        camera: camera
    }

    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                clearColor: Qt.rgba(0, 0.5, 1, 1)
                camera: camera
            }
        },
        InputSettings { }
    ]

    PhongMaterial {
        id: carMaterial
    }

    Mesh {
        id: carMesh
        source: "resources/aventador.obj"
    }

    Entity {
        id: carEntity
        components: [ carMesh, carMaterial ]
    }
}

How do I get the camera to rotate around the mesh object?

3 Answers

you should use a mouse or keyboard to do this . when you use OrbitCameraController or FirstPersonCameraController you cant have our control . I use this code instead of OrbitCameraController.

Entity{
id: root
property Camera camera;
property real dt: 0.001
property real linearSpeed: 1
property real lookSpeed: 500
property real zoomLimit: 0.16

MouseDevice {
    id: mouseDevice
    sensitivity: 0.001 // Make it more smooth
}

MouseHandler {
    id: mh
    readonly property vector3d upVect: Qt.vector3d(0, 1, 0)
    property point lastPos;
    property real pan;
    property real tilt;
    sourceDevice: mouseDevice

    onPanChanged: root.camera.panAboutViewCenter(pan, upVect);
    onTiltChanged: root.camera.tiltAboutViewCenter(tilt);

    onPressed: {
        lastPos = Qt.point(mouse.x, mouse.y);
    }
    onPositionChanged: {
        // You can change the button as you like for rotation or translation
        if (mouse.buttons === 1){ // Left button for rotation
            pan = -(mouse.x - lastPos.x) * dt * lookSpeed;
            tilt = (mouse.y - lastPos.y) * dt * lookSpeed;
        } else if (mouse.buttons === 2) { // Right button for translate
            var rx = -(mouse.x - lastPos.x) * dt * linearSpeed;
            var ry = (mouse.y - lastPos.y) * dt * linearSpeed;
            camera.translate(Qt.vector3d(rx, ry, 0))
        } else if (mouse.buttons === 3) { // Left & Right button for zoom
            ry = (mouse.y - lastPos.y) * dt * linearSpeed
            zoom(ry)
        }

        lastPos = Qt.point(mouse.x, mouse.y)
    }
    onWheel: {
        zoom(wheel.angleDelta.y * dt * linearSpeed)
    }

    function zoom(ry) {
        if (ry > 0 && zoomDistance(camera.position, camera.viewCenter) < zoomLimit) {
            return
        }

        camera.translate(Qt.vector3d(0, 0, ry), Camera.DontTranslateViewCenter)
    }

    function zoomDistance(posFirst, posSecond) {
        return posSecond.minus(posFirst).length()
    }
}}

create a new qml class and call it for example SOrbitCameraController or anything you want then use it instead of OrbitCameraController and take camera to this class.

I know this is an old post but since I found my answer and this stumped me too, here is what I adjusted:

I found that all I needed to do was to set the up Vector to zero, I am writing with pyqt so mine looked like this:

camera.setUpVector(QVector3D(0.0, 0.0, 0.0))

The reason being that after this I was able to lock the right-mouse button controls and rotate around the mesh with the left-mouse button controls.

Related