Qt3D围绕网格旋转相机

5

我最近开始学习Qt/QML/C++,试图构建一个非常基本的三维场景,以使相机围绕网格对象旋转。

我发现很难跟随示例,并且发现文档没有提供任何有用的指令。似乎也没有太多教程可用,也许我正在错误的地方寻找。

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

我该如何使相机围绕网格对象旋转?


你还没有提出任何问题。你有代码,目前看起来不错。编译时是否有错误?它是否不能做你想要的事情?如果没有问题,就无法回答。 - Aziuth
将相机的视图中心设置为您想要围绕旋转的点。 - peppe
4个回答

2
OrbitCameraController可以沿轨道移动相机。要使其围绕网格旋转,您可以将相机的viewCenter设置为网格位置(包含网格的实体变换的平移),然后使用键盘/鼠标将其旋转。
因此,请添加:
Transform{
        id: carTransform
        translation: Qt.vector3d(5.0, 5.0, 5.0) //random values, choose your own
}

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

viewCenter: carTransform.translation

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 并将相机传递到这个类中。


0

我知道这是一篇旧文章,但由于我找到了答案并且这也让我困扰不已,这里是我所做的调整:

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

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

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

0
我找到了这个有用的信息。
Q_INVOKABLE void tiltAboutViewCenter(float angle);

Q_INVOKABLE void panAboutViewCenter(float angle);

Q_INVOKABLE void panAboutViewCenter(float angle, const QVector3D &axis);

Q_INVOKABLE void rollAboutViewCenter(float angle);

这就是你想要的。

1
根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到更多关于如何撰写好回答的信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接