Qt3D围绕网格旋转相机

时间:2017-07-28 09:01:19

标签: c++ qt qml qt3d

我最近开始学习Qt / QML / C ++并尝试构建一个非常基本的3D场景来围绕网格物体旋转相机。

我发现很难遵循这些示例,我发现文档没有提供任何有用的说明。似乎也没有很多教程,也许我正在寻找错误的地方。

的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 ]
    }
}

如何让相机围绕网格对象旋转?

3 个答案:

答案 0 :(得分:1)

OrbitCameraController允许沿轨道路径移动摄像机。要使其围绕网格旋转,可以将摄像机的viewCenter设置为网格的位置(包含网格的实体的变换的平移),并使用键盘/鼠标旋转它。

添加:

Transform{
        id: carTransform
        translation: Qt.vector3d(5.0, 5.0, 5.0) //random values, choose your own
}

并将转换添加到实体的组件中。 将摄像机的视图中心更改为

viewCenter: carTransform.translation

答案 1 :(得分:0)

我知道这是一篇过时的文章,但是由于我找到了答案并且这也让我感到困惑,所以我做了以下调整:

我发现我需要做的就是将Vector设置为零,我正在用pyqt编写,所以我的样子是这样的:

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

原因是在此之后,我能够锁定鼠标右键控件并使用鼠标左键控件围绕网格旋转。

答案 2 :(得分:0)

您应该使用鼠标或键盘来执行此操作。 当您使用 OrbitCameraControllerFirstPersonCameraController 你不能控制我们。我使用这个 code 而不是 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()
    }
}}

创建一个新的 qml 类并将其命名为例如 SOrbitCameraController 或您想要的任何内容,然后使用它代替 OrbitCameraController 并将相机带到此类。