5

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

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

主文件

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

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

4

3 回答 3

2

The OrbitCameraController allows to move the camera along an orbital path. To make it rotate around the mesh, you could set the viewCenter of the camera to the position of the mesh (translation of the transform of the entity containing the mesh) and use your keyboard/mouse to rotate it around.

So add:

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

and add the transform to the components of the entity. Change the viewCenter of the camera to

viewCenter: carTransform.translation
于 2017-08-24T07:46:11.750 回答
1

您应该使用鼠标或键盘来执行此操作。当您使用OrbitCameraControllerFirstPersonCameraController时 ,您无法控制。我使用此代码而不是 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 并将相机带到这个类。

于 2021-06-14T23:13:18.643 回答
0

我知道这是一篇旧帖子,但因为我找到了答案,这也难倒了我,以下是我调整的内容:

我发现我需要做的就是将向量设置为零,我正在用 pyqt 编写,所以我的看起来像这样:

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

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

于 2020-02-07T18:58:07.627 回答